RecyclerView 实现瀑布流的正确姿势

首先来看一下瀑布流效果:

加载的数据根据自己需求自己定义。

来说一下具体实现:

private RecyclerView rlv;

private FlashApapter mAdapter;

//设置layoutManager
StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
//解决item跳动
manager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
rlv.setLayoutManager(manager);

mAdapter = new FlashApapter (this,datas);

rlv.setAdapter(mAdapter);

下面看下FlashAdapter的具体实现:

public class FlashAdapter extends RecyclerView.Adapter<FlashAdapter.MyHolder> {

    private Context context;
    private List<VideoBean> flashlyBeans;
    private int baseWidth = 0;
    private flashCallBack mCallBack;

扫描二维码关注公众号,回复: 2487139 查看本文章

    public FlashAdapter(Context context, List<VideoBean> flashlyBeans, flashCallBack mCallBack) {
        this.context = context;
        this.flashlyBeans = flashlyBeans;
        this.mCallBack = mCallBack;
        int screenWidth = TCommonUtils.getScreenWidth(context);
        baseWidth = screenWidth/2;
    }

    @Override
    public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = View.inflate(context, R.layout.item_flashly, null);
        return new MyHolder(view);
    }

    @Override
    public void onBindViewHolder(MyHolder holder, int position) {
        VideoBean bean = flashlyBeans.get(position);
        Glide.with(context)
                .load(bean.getImgUrl()).dontAnimate()
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .placeholder(R.drawable.bg_theme)
                .into(holder.mIvImg);

        if (mCallBack != null) {
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int index = (int) v.getTag();
                    mCallBack.onItemClick(index);
                }
            });
        }
    }

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

    public class MyHolder extends RecyclerView.ViewHolder {
        @BindView(R.id.iv_img)
        ImageView mIvImg;

        public MyHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }

    public interface flashCallBack {
        void onItemClick(int position);
    }
}

这时我们的基本实现完成了,然后运行,效果并不是瀑布流。郁闷。

然后我们发现,我们需要给每个item设置一个高度,这个高度不是固定的。

然后再运行,瀑布流效果是实现了。但是由于页面是分页加载,当我们上拉加载更多后,然后再回到顶部,发现顶部item有留白和位置跳动的问题,还是郁闷。

问题到底出在哪里?

答案是这样的,当我们上拉加载更多后,调用了 mAdapter.notifyDataSetChanged(),进行了整个页面的刷新,这样就会重新计算图片高度,造成布局错乱。那既然这样,我们不要重新加载布局。换成

mAdapter.notifyItemInserted(prePosition + 1),从数据变化的地方加载新布局。

这样就解决了留白和位置跳动问题。

最后总结一下:瀑布流效果关键有两点:第一、给图片设置不同的高度,并保存下来;第二、加载更多时,从新增数据开始的位置开始加载,不要notifyDataChanged,而是notifyItemInserted(position+1)。

猜你喜欢

转载自blog.csdn.net/qq_33275597/article/details/81227863
今日推荐