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

最近公司,开发仿快手的短视频音乐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);
}

你可能感兴趣的:(RecyclerView瀑布流,项目解决item跳动,留白,闪烁)