android瀑布流顶部留白,RecyclerView瀑布流空白、重新排序原因及解决办法

RecyclerView 可以很轻松实现瀑布流,使用StaggeredGridLayoutManager 即可,但也暴露出了很多问题。

1.列表重新排序

大家应该都遇到过下面的问题,列表滚动出现了左右item位置切换的,这个问题解决倒不难。

layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);

GAP_HANDLING_NONE表示不对任何空白间隙做处理。

但也由此引发了下面的问题。

当列表出现空白间隙时,StaggeredGridLayoutManager其实是会对列表重排序来消除间隙,设置GAP_HANDLING_NONE后,屏蔽了这种机制,导致了顶部item空白的出现。

2.滑动到列表顶部时顶部留白

如下图所示

d34075c0f287

image.png

首先google了百度的一番,网上有一些解决办法,

layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);//设置不对空白间隙处理

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

@Override

public void onScrollStateChanged(RecyclerView recyclerView, int newState) {

super.onScrollStateChanged(recyclerView, newState);

staggeredGridLayoutManager.invalidateSpanAssignments();//重新布局

}

@Override

public void onScrolled(RecyclerView recyclerView, int dx, int dy) {

super.onScrolled(recyclerView, dx, dy);

}

});

public void invalidateSpanAssignments() {

// 将spanIndex数组清空,进行重绘,后面会讲解mLazySpanLookup的作用

mLazySpanLookup.clear();

requestLayout();

}

这种方式确实是“解决了”空白的问题,但还是有一些问题

1.造成图片闪烁

invalidateSpanAssignments实现是重新绘制一次,由于是在滚动状态发生变化时调用,每次滚动都会造成至少2-3次的重绘,资源浪费。

在这里说一个更好的解决方案:

使用notifyItemRangeChanged(或者notifyItemRangeInsert流程和notifyItemRangeChanged一样,感谢Magic丶海提醒)替代notifyDataSetChanged进行列表刷新。

造成空白的原因

大家再看一下下面这张图,左右两张图中item的位置变化。

d34075c0f287

image.png

左侧图片是默认情况下初始化时的展示,右侧图是加载了分页数据,重新回滚到顶部时的展示,显然右侧图的位置较之前出现了错乱。

我们的RecycleView一般都是有分页的,新增数据源之后,需要调用notifyDataSetChanged进行列表的刷新,如果我们列表只有一页不会出现空白的问题,当有分页数据时候刷新列表时就会出现空白,这是由于分页刷新列表造成的,但其最根本的原因是刷新时spanIndex索引出现了变化。下面将分析源码是如何造成这种情况的。我们先看下RecyclewView的测量布局流程。

d34075c0f287

image.png

上面的流程图忽略了一部分判断条件,为了更直观的分析,我们再简化一下:

瀑布流使用的是StaggeredGridLayoutManager,StaggeredGridLayoutManager中isAutoMeasureEnabled的实现是设置GAP_HANDLING_NONE时,才为false,此处没有设置则为true。

RecycleView 设置的layout_width和layout_height都是match_parent, 测量模式为EXACTLY,所以measureSpecModeIsExactly 为true.

那么流程图简化为如下图:

d34075c0f287

image.png

LayoutManger负责的item的布局,因为是瀑布流,我们去看一下在StaggeredGridLayoutManager中是如何对处理item v

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值