marclee44 / me

1 stars 0 forks source link

MVVM模式下RecyclerView使用Data Binding的基本实现 #9

Open marclee44 opened 3 years ago

marclee44 commented 3 years ago

RecyclerView可以轻松高效地显示大量数据,事先定义每个列表项的外观,并根据需要动态创建元素。 列表中的每个独立元素都由一个ViewHolder对象进行定义。创建ViewHolder时,它并没有任何关联的数据。创建ViewHolder后,RecyclerView会将其绑定到其数据。可以通过扩展RecyclerView.ViewHolder来定义ViewHolderRecyclerView会请求这些视图,并通过在Adapter中调用方法,将视图绑定到其数据。可以通过扩展RecyclerView.Adapter来定义Adapter

首先是单个列表项的布局

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>
        <variable
            name="model"
            type="com.example.test.models.Item" />
    </data>

    <androidx.cardview.widget.CardView
        ...>
        <LinearLayout
            ...
            android:id="@+id/item">
            <ImageView
                ...
                app:imageUrl="@{model.pic}" />
            <TextView
                ...
                android:text="@{model.name}" />
        </LinearLayout>
    </androidx.cardview.widget.CardView>
</layout>

这是一个简单的带Data Binding的列表项,布局为图片+文字的CardView 有2个约定名称modelitem需要说明。model用于在Adapter中为单个列表项设置数据,item则用来绑定点击事件

接下来实现Adapter和ViewHolder

确定布局后,需要实现AdapterViewHolder。这两个类配合使用,共同定义数据的显示方式。ViewHolder是包含列表中各列表项的布局的View的封装容器。Adapter会根据需要创建ViewHolder对象,还会为这些视图设置数据。将视图与其数据相关联的过程称为“绑定”。 定义Adapter时,需要重写三个关键方法:

ViewHolder比较简单,就是在“绑定”

    class ViewHolder extends RecyclerView.ViewHolder {
        private ListItemBinding mBinding;

        public ViewHolder(@NonNull ListItemBinding binding) {
            super(binding.getRoot());
            mBinding = binding;
        }
    }

然后就是使用了

Activity中只需要把数据源给到Adapter,绑定点击事件,并订阅ViewModel中的LiveData变化,实时更新即可

    private RecyclerAdapter mAdapter;
    private MainViewModel mViewModel;
    private RecyclerView mListRecycler;

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

        mListRecycler = findViewById(R.id.viewList);
        mViewModel = new ViewModelProvider(this).get(MainViewModel.class);
        mViewModel.init();
        mViewModel.getList().observe(this, data -> mAdapter.setData(data));

        initRecyclerView();
    }

    private void initRecyclerView() {
        mAdapter = new RecyclerAdapter(mViewModel.getList().getValue(), item -> {
            //item Clicked
        });
        mListRecycler.setLayoutManager(new LinearLayoutManager(this));
        mListRecycler.setHasFixedSize(true);
        mListRecycler.setAdapter(mAdapter);
    }