欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MVVM模式下RecyclerView与databinding的结合(2)

程序员文章站 2022-06-09 20:18:56
...

MVVM模式下RecyclerView与databinding的结合(2)
Demo地址

https://github.com/linqinen708/MyDatabindingRecyclerView

很早以前,写过一篇文章
MVVM模式下RecyclerView与databinding的结合

讲述了如何通过封装RecyclerView和谷歌的Databinding的结合,后来在开发中,逐渐发现其不完善的地方,于是自己通过不断摸索和优化,使其具备下拉刷新和上拉加载功能(不借用任何第三方库),并且封装了一些方法,方便直接逻辑判断调用,下面简单介绍下:

1.首先创建一个自己的adapter,继承自BaseBindingAdapter,传入2个参数(一个你自己需要的bean类,和Databinding的xml布局类)

public class MyAdapter extends BaseBindingAdapter<MyBean, AdapterLayoutBinding> {
    public MyAdapter(Context context) {
        super(context);
    }

    @Override
    protected int getLayoutResId() {
        return R.layout.adapter_layout;
    }

    @Override
    protected void onBindItem(AdapterLayoutBinding binding, MyBean bean, int position) {
        binding.setBean(bean);
        binding.setViewModel(new MyViewModel(bean));
    }
}

你没有看错,整个adapter非常的简单,重写getLayoutResId方法返回你自己的xml布局文件,再在
onBindItem方法中绑定你所需要的数据,就完成了一个adapter的最基本操作,不需要写任何onCreateViewHolder方法和创建自己的ViewHolder,因为这些我都已经在BaseBindingAdapter中封装好了

2.传入数据
传统的adapter都会去创建一个List,我直接对其封装在BaseBindingAdapter中,所以在使用时,你只用调用
mAdapter.getItems().add或者addAll方法即可,并且不需要再使用notifyItemRangeInserted或者notifyDataSetChanged方法去刷新数据,我在BaseBindingAdapter也封装了数据的监听,可以动态刷新数据

mAdapter.getItems().add(new MyBean("谷歌1", 25, R.drawable.ic_launcher_foreground, true));

至此,一个简单的BaseBindingAdapter就可以使用了

不过这种adapter实在太简单了,在很多场景中可能不够用,比如需要HeaderView和FooterView的地方,或者可能复杂的业务逻辑需要多个itemView的时候,所以我对原本的BaseBindingAdapter进行了额外的优化和封装,让其可用性更强一些

1.HeaderView的使用

只需要在自己的adapter中,重新getHeaderViewLayoutResId方法,传入自己的xml布局即可

  @Override
    protected int getHeaderViewLayoutResId() {
        return R.layout.adapter_head_view_layout;
    }

如果也需要动态修改HeaderView的数据怎么办呢?

只要重写onBindViewHolder方法即可
(注意!!!千万不要删除super.onBindViewHolder(holder, position),父类中已经封装了普通itemView的onBindItem方法,如果删除,则无法正常调用)

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        super.onBindViewHolder(holder, position);
        if (holder instanceof HeaderViewHolder) {
            AdapterHeadViewLayoutBinding binding = DataBindingUtil.getBinding(holder.itemView);
            if (binding != null) {
                binding.tvHeaderView.setText("大家好,我是HeaderView");
            }
        }
}

2.FooterView的使用
与HeaderView类似,重写getFooterViewLayoutResId方法,
不过我做了一点额外的封装处理,因为一般的FooterView都是显示上拉加载中,或者暂无更多数据等功能,所以我做了一个非常简单的adapter_default_footer_view.xml布局,布局里面只有一个TextView,默认显示文字“暂无更多数据”
小伙伴们可以直接调用

mAdapter.showFooterView(false)

参数表示是否显示FooterView
或者

mAdapter.showLoadMore(false) 

false 暂无更多数据,true 正在加载…

不必在adapter中重写getFooterViewLayoutResId,就可以直接展示FooterView

3.需要根据后台接口的数据,动态展示FooterView的 上拉加载更多,或者 暂无更多数据

直接将后台的list传入我封装的方法toggleFootView中,
根据是否有数据,展示FooterView的暂无更多数据功能

mAdapter.toggleFootView(collection);

直接将后台的list传入我封装的方法toggleLoadMore中,
根据是否有数据,展示FooterView的“正在加载…” 或者“暂无更多数据”功能

mAdapter.toggleLoadMore(collection)

4.关于上拉加载更多
RecyclerView 自带的上拉加载更多

5.item的点击事件

 mAdapter.setOnItemClickListener(new BaseBindingAdapter.OnItemClickListener<MyBean>() {
            @Override
            public void onItemClick(MyBean bean, int position) {
                Toast.makeText(getBaseContext(), "点击第" + position + "个", Toast.LENGTH_SHORT).show();
            }
        });

Databinding有很多坑,新手很容易掉坑里,附上自己整理的常见的一些方法的调用
谷歌的databinding常见用法