RecyclerView瀑布流,项目解决item跳动,留白,闪烁

来源:互联网 发布:剑三高冷正太捏脸数据 编辑:程序博客网 时间:2024/05/21 00:17

最近公司,开发仿快手的短视频音乐APP,其中首页自然需要用到瀑布流,下面说下自己碰到的坑:

瀑布流,首先,肯定图片要设置不同的高度,布局中图片自然是用wrap_content,下面说坑:

item到处跳动,甚至左右两列切换,解决办法:

manager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);

这个自不用说,网上一搜一大把。但是即使这样,当你加载多页后,在网上滑到第一页,会出现空白,或者图片交错,这时候,你网上一搜,很多人说:

xRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {    @Override    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {        super.onScrollStateChanged(recyclerView, newState);        manager.invalidateSpanAssignments();    }});
这样一来,好像首页不留白, 但是,但是我相信很多人下拉加载更多的过程中肯定会发现图片会闪烁,然后往回滑动的时候出现部分图片跳来跳去,网上搜的这个方法太不靠谱,我折腾了很久,网上有作者贴出源码:http://www.jianshu.com/p/81e088000ba6,不会出现我的情况,而且人家也没有用上面的监听方法。后面我尝试了很多,比较了很多,解决办法一句代码:下拉加载更多,一定是调用
notifyItemInserted(加载更多开始position);

而不是notifyDataSetChange();只要这样去加载更多,理论上图片闪烁,和留白问题都解决了。我的图片加载是Glide。如果有问题可一起讨论。

另外仿快手瀑布流,瀑布流左右不留间距,只有中间留间距的办法,一开始困扰了我好久,如果不是瀑布流,自然可以对每个item判断是左边还是右边,然后分别设置LayoutParams,但是在瀑布流中怎么知道对应的item是左边还是右边呢?关键就是怎么知道对应的item是左边还是右边。我说一下我实现的思路,首先肯定需要获取每个item的高度,新建一个hashMap,用于记录item是左边还是右边,增加两个属性,左、右累加高度,通过逻辑去判断每个item的高度是加在做高度上,还是右高度上,判断左>右,自然这个item应该在右边,否则左边,并且通过前面的hashMap保存好,下次只要判断对应positon是否存在,然后拿出来即可!噼里啪啦说了这么多,肯定很枯燥,我大概贴一下我的代码吧,当然有些写的不是很好的地方,多多批评!

//计算高度if (!imageHeightMap.containsKey(position)) {    paramsHeight = (int) ((rankingData.getLength() / (float) rankingData.getWidth()) * width);    imageHeightMap.put(position, paramsHeight);} else {    paramsHeight = imageHeightMap.get(position);}//判断是左边还是右边if (!isLeftMap.containsKey(position)) {    if (leftHeight < rightHeight) {        isLeft = true;    } else if (leftHeight == rightHeight) {        isLeft = !isLeft;    } else {        isLeft = false;    }    //高度累加    if (isLeft) {        leftHeight = leftHeight + paramsHeight + bottomHeight;    } else {        rightHeight = rightHeight + paramsHeight + bottomHeight;    }    isLeftMap.put(position, isLeft);} else {    isLeft = isLeftMap.get(position);}//重新设置宽高ViewGroup.LayoutParams layoutParams = viewHolder.ivItemBackground.getLayoutParams();layoutParams.height = paramsHeight;viewHolder.ivItemBackground.setLayoutParams(layoutParams);//整个item设置高度和左右边距if (isLeft) {    StaggeredGridLayoutManager.LayoutParams layoutLeftParams = (StaggeredGridLayoutManager.LayoutParams) viewHolder.itemView.getLayoutParams();    layoutLeftParams.leftMargin = DisplayUtil.dip2px(mContext, 0);    layoutLeftParams.rightMargin = DisplayUtil.dip2px(mContext, (float) 1);    viewHolder.itemView.setLayoutParams(layoutLeftParams);} else {    StaggeredGridLayoutManager.LayoutParams layoutRightParams = (StaggeredGridLayoutManager.LayoutParams) viewHolder.itemView.getLayoutParams();    layoutRightParams.leftMargin = DisplayUtil.dip2px(mContext, (float) 1);    layoutRightParams.rightMargin = DisplayUtil.dip2px(mContext, 0);    viewHolder.itemView.setLayoutParams(layoutRightParams);}

阅读全文
3 0
原创粉丝点击