Android-浅谈RecyclerView瀑布流Item位置变换问题

背景

根据项目需求实现瀑布流的效果,当然肯定会遇到一系列问题,看了一些网上关于RecyclerView中实现瀑布流时出现的Item错位问题,有一些自己的看法。

介绍

manager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
//防止item 交换位置
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        manager.invalidateSpanAssignments(); //防止第一行到顶部有空白区域
    }
});

这是网上说的最多的方法,但是有些疑问:

  1. 重新绘制不影响性能吗
  2. 写这么多代码的目的是什么呢
  3. 都知道是复用机制捣的鬼,为何不从源头解决问题嘞

尝试

带着这些疑问进行尝试,结果很意外!

  • 布局代码
    Android-浅谈RecyclerView瀑布流Item位置变换问题_第1张图片
  • Item布局代码
    Android-浅谈RecyclerView瀑布流Item位置变换问题_第2张图片
  • 具体实现
public class MainActivity extends Activity {
    
    @BindView(R.id.rv)
    RecyclerView rv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        //数据源
        List list = new ArrayList<>();
        list.add("http://img5.imgtn.bdimg.com/it/u=3186248013,2280355878&fm=26&gp=0.jpg");
        list.add("http://img3.imgtn.bdimg.com/it/u=1139548503,474948438&fm=26&gp=0.jpg");
        list.add("http://img1.imgtn.bdimg.com/it/u=1378897116,1103132713&fm=26&gp=0.jpg");
        list.add("http://img3.imgtn.bdimg.com/it/u=222247294,2919493301&fm=26&gp=0.jpg");
        list.add("http://img3.imgtn.bdimg.com/it/u=3465791092,3536705985&fm=26&gp=0.jpg");
        list.add("http://img1.imgtn.bdimg.com/it/u=1153867435,2125447866&fm=26&gp=0.jpg");
        list.add("http://img5.imgtn.bdimg.com/it/u=1219331396,194612919&fm=26&gp=0.jpg");
        list.add("http://img2.imgtn.bdimg.com/it/u=1818409116,3077403258&fm=26&gp=0.jpg");
        list.add("http://img3.imgtn.bdimg.com/it/u=4259389820,773858189&fm=26&gp=0.jpg");
        list.add("http://img3.imgtn.bdimg.com/it/u=1989006325,3723192324&fm=26&gp=0.jpg");
        list.add("http://img1.imgtn.bdimg.com/it/u=3403067419,2698923886&fm=26&gp=0.jpg");
        list.add("http://img0.imgtn.bdimg.com/it/u=2590563761,1702746769&fm=26&gp=0.jpg");
        list.add("http://img1.imgtn.bdimg.com/it/u=3110666966,1649694957&fm=26&gp=0.jpg");
        list.add("http://img0.imgtn.bdimg.com/it/u=526293223,2881312121&fm=26&gp=0.jpg");
        list.add("http://img4.imgtn.bdimg.com/it/u=2503161942,1763219992&fm=26&gp=0.jpg");
        list.add("http://img3.imgtn.bdimg.com/it/u=2555204911,3508488420&fm=26&gp=0.jpg");
        list.add("http://img0.imgtn.bdimg.com/it/u=3663208266,221295462&fm=26&gp=0.jpg");
        list.add("http://img1.imgtn.bdimg.com/it/u=184317050,1666959161&fm=26&gp=0.jpg");

        //随机高度
        List list1 = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            list1.add((int) (100 + Math.random() * 500));
        }

        int width = getWindowManager().getDefaultDisplay().getWidth();//屏幕宽
        rv.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
        rv.setAdapter(new RecyclerView.Adapter() {
            @NonNull
            @Override
            public Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                return new Holder(LayoutInflater.from(MainActivity.this).inflate(R.layout.itme, null));
            }

            @Override
            public void onBindViewHolder(@NonNull Holder holder, int position) {
                RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) holder.textView.getLayoutParams();
                params.width = width / 2 - 20;
                params.height = list1.get(position);
                holder.textView.setLayoutParams(params);
                Glide.with(holder.textView).load(list.get(position)).into(holder.textView);
            }

            @Override
            public int getItemCount() {
                return list.size();
            }
        });

    }

    class Holder extends RecyclerView.ViewHolder {
        ImageView textView;

        public Holder(@NonNull View itemView) {
            super(itemView);
            textView = itemView.findViewById(R.id.iv);
        }
    }

}

核心思想就是在源数据那里生成随机高度,在代码RecyclerView来回滑动的过程中即使复用也不会重新生成新的高度,这样就从源头上解决了问题,不要写那么多的代码逻辑,也不影响性能!即使是在加载更多数据的时候也直接设置好高度就OK了!

效果

视频太大,转成JIF图片有点失真了╮(╯▽╰)╭

结语

记录生活点滴,学习前辈经历,不断完善自己,感谢生活有你!!!

你可能感兴趣的:(Android)