Open marclee44 opened 3 years ago
RecyclerView可以轻松高效地显示大量数据,事先定义每个列表项的外观,并根据需要动态创建元素。 列表中的每个独立元素都由一个ViewHolder对象进行定义。创建ViewHolder时,它并没有任何关联的数据。创建ViewHolder后,RecyclerView会将其绑定到其数据。可以通过扩展RecyclerView.ViewHolder来定义ViewHolder。 RecyclerView会请求这些视图,并通过在Adapter中调用方法,将视图绑定到其数据。可以通过扩展RecyclerView.Adapter来定义Adapter。
RecyclerView
ViewHolder
RecyclerView.ViewHolder
Adapter
RecyclerView.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个约定名称model和item需要说明。model用于在Adapter中为单个列表项设置数据,item则用来绑定点击事件
Data Binding
CardView
model
item
接下来实现Adapter和ViewHolder
确定布局后,需要实现Adapter和ViewHolder。这两个类配合使用,共同定义数据的显示方式。ViewHolder是包含列表中各列表项的布局的View的封装容器。Adapter会根据需要创建ViewHolder对象,还会为这些视图设置数据。将视图与其数据相关联的过程称为“绑定”。 定义Adapter时,需要重写三个关键方法:
View
@NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { ListItemBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.list_item, parent, false); return newViewHolder(binding); }
onBindViewHolder() RecyclerView调用此方法将ViewHolder与数据相关联。此方法会提取适当的数据,并使用该数据填充ViewHolder的布局。
@Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { Item item = mData.get(position); holder.mBinding.setModel(item); holder.mBinding.item.setOnClickListener(v -> { if (mListener != null) { mListener.onItemClicked(mData.get(position)); } }); } public interface ItemClickedListener { void onItemClicked(Item item); }
此处的holder.mBinding.setModel()就是在为上文单个列表项中的model设置数据 holder.mBinding.item,则是在为item绑定点击事件
holder.mBinding.setModel()
holder.mBinding.item
@Override public int getItemCount() { if (mData != null) { return mData.size(); } else { return 0; } }
同时,需要提供数据更新接口
public void setData(List<Item> data) { mData = data; notifyDataSetChanged(); }
ViewHolder比较简单,就是在“绑定”
class ViewHolder extends RecyclerView.ViewHolder { private ListItemBinding mBinding; public ViewHolder(@NonNull ListItemBinding binding) { super(binding.getRoot()); mBinding = binding; } }
然后就是使用了
Activity中只需要把数据源给到Adapter,绑定点击事件,并订阅ViewModel中的LiveData变化,实时更新即可
Activity
ViewModel
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); }
RecyclerView
可以轻松高效地显示大量数据,事先定义每个列表项的外观,并根据需要动态创建元素。 列表中的每个独立元素都由一个ViewHolder
对象进行定义。创建ViewHolder
时,它并没有任何关联的数据。创建ViewHolder
后,RecyclerView
会将其绑定到其数据。可以通过扩展RecyclerView.ViewHolder
来定义ViewHolder
。RecyclerView
会请求这些视图,并通过在Adapter
中调用方法,将视图绑定到其数据。可以通过扩展RecyclerView.Adapter
来定义Adapter
。这是一个简单的带
Data Binding
的列表项,布局为图片+文字的CardView
有2个约定名称model
和item
需要说明。model
用于在Adapter
中为单个列表项设置数据,item
则用来绑定点击事件确定布局后,需要实现
Adapter
和ViewHolder
。这两个类配合使用,共同定义数据的显示方式。ViewHolder
是包含列表中各列表项的布局的View
的封装容器。Adapter
会根据需要创建ViewHolder
对象,还会为这些视图设置数据。将视图与其数据相关联的过程称为“绑定”。 定义Adapter
时,需要重写三个关键方法:RecyclerView
需要创建新的ViewHolder
时,它都会调用此方法。此方法会创建并初始化ViewHolder
及其关联的View
,但不会填充视图的内容,因为ViewHolder
此时尚未绑定到具体数据。onBindViewHolder()
RecyclerView
调用此方法将ViewHolder
与数据相关联。此方法会提取适当的数据,并使用该数据填充ViewHolder
的布局。此处的
holder.mBinding.setModel()
就是在为上文单个列表项中的model
设置数据holder.mBinding.item
,则是在为item
绑定点击事件RecyclerView
调用此方法来获取数据集的大小,并确定什么时候没有更多的列表项可以显示。同时,需要提供数据更新接口
ViewHolder
比较简单,就是在“绑定”Activity
中只需要把数据源给到Adapter
,绑定点击事件,并订阅ViewModel
中的LiveData变化,实时更新即可