RecyclerView、ViewHolder和Adapter
首先,我们要明确这三个类各自的任务和逻辑结构。
RecyclerView 任务仅限于回收和定位屏幕上的 View ,RecyclerView 自身不会创建视图, 他通过 Adapter 创建。
Adapter 是一个控制器对象, 从模型层获取数据, 然后提供给 RecyclerView 显示,是沟通的桥梁。 他负责:
- 创建必要的 ViewHolder
-
绑定 ViewHolder 至模型层数据
Adpater 与 RecyclerView 之间的桥梁
ViewHolder 负责容纳 View 视图
ViewHolder 配合 RecyclerView 使用
使用 RecyclerView
mCrimeRecyclerView = view.findViewById(R.id.crime_recycler_view);
mCrimeRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
当我们创建一个 RecyclerView 时, 我们首先要对他进行布局加载, 更要注意的是托管给 LayoutManager。没有 LayoutManager 的支持, 不仅 RecyclerView 无法正常工作, 还会导致应用崩溃。这是为什么呢?实际上, RecyclerView 不会亲自摆放屏幕上的列表项, 摆放的任务委托给了 LayoutManager。 LayoutManager 还负责定义屏幕上的滚动行为(竖着滚还是横着滚等等)
ViewHolder 显示视图
private class CrimeHolder extends RecyclerView.ViewHolder{
public CrimeHolder(LayoutInflater inflater, ViewGroup parent){
super(inflater.inflate(R.layout.list_item_crime, parent, false));
}
}
在 CrimeHolder 的构造方法中, 我们首先实例化list_item_crime布局,然后传给 super 方法, 也就是 ViewHolder 的构造方法。 基类ViewHolder 因而实际引用这个视图。
Adapter架起桥梁(绑定ViewHolder)
private class CrimeAdapter extends RecyclerView.Adapter<CrimeHolder>{
private List<Crime> mCrimes;
public CrimeAdapter(List<Crime> crimes){
mCrimes = crimes;
}
@Override
public int getItemCount() {
return mCrimes.size();
}
@NonNull
@Override
public CrimeHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
return new CrimeHolder(layoutInflater, parent);
}
@Override
public void onBindViewHolder(@NonNull CrimeHolder holder, int position) {
Crime crime = mCrimes.get(position);
//令每个ViewHolder绑定数据,具体bind函数略
holder.bind(crime);
}
}
RecyclerView 需要新的ViewHolder 来显示列表时,会调用 onCcreateViewHolder 方法。在这个方法内部, 我们创建一个 LayoutInflater, 然后用他创建 CrimeHolder。
CrimeAdapter 必须覆盖 onBindViewHolder 方法。
桥梁的具体过程:
- 首先,调用 Adapter 的 getItemCount() 方法, RecyclerView 询问数组里列表中包含多少个对象。
- 接着,RecyclerView 调用 Adapter 的 onCreateViewHolder(ViewGroup, int) 方法创建 ViewHolder 及其要显示的视图。
- 最后,RecyclerView 会传入 ViewHolder 及其位置, 调用 onBindViewHolder(ViewHolder, int)方法。Adapter 会找到目标位置的数据并将其绑定到 ViewHolder 的视图上。所谓绑定,就是使用模型数据填充视图。
最后,别忘了关联 Adapter 和 RecyclerView
private void updateUI(){
CrimeLab crimeLab = CrimeLab.get(getActivity());
List<Crime> crimes = crimeLab.getCrimes();
mAdapter = new CrimeAdapter(crimes);
//将具体的 RecyclerView 和 Adapter 关联到一起
mCrimeRecyclerView.setAdapter(mAdapter);
}
网友评论