前言
上一篇,说了ItemDecoration
,这一篇,我们来说说RecyclerView
的回收复用逻辑。
- 【Android进阶】RecyclerView之ItemDecoration(一)
- 【Android进阶】RecyclerView之缓存(二)
- 【Android进阶】RecyclerView之绘制流程(三)
问题
假如有100个item
,首屏最多展示2个半(一屏同时最多展示4个),RecyclerView
滑动时,会创建多少个viewholder
?
先别急着回答,我们写个 demo 看看
首先,是item
的布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv_repeat"
android:layout_width="match_parent"
android:layout_height="200dp"
android:gravity="center" />
<TextView
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="@color/colorAccent" />
</LinearLayout>
然后是RepeatAdapter
,这里使用的是原生的Adapter
public class RepeatAdapter extends RecyclerView.Adapter<RepeatAdapter.RepeatViewHolder> {
private List<String> list;
private Context context;
public RepeatAdapter(List<String> list, Context context) {
this.list = list;
this.context = context;
}
@NonNull
@Override
public RepeatViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(context).inflate(R.layout.item_repeat, viewGroup, false);
Log.e("cheng", "onCreateViewHolder viewType=" + i);
return new RepeatViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull RepeatViewHolder viewHolder, int i) {
viewHolder.tv_repeat.setText(list.get(i));
Log.e("cheng", "onBindViewHolder position=" + i);
}
@Override
public int getItemCount() {
return list.size();
}
class RepeatViewHolder extends RecyclerView.ViewHolder {
public TextView tv_repeat;
public RepeatViewHolder(@NonNull View itemView) {
super(itemView);
this.tv_repeat = (TextView) itemView.findViewById(R.id.tv_repeat);
}
}
}
在Activity
中使用
List<String> list = new ArrayList<>();
for (int i = 0; i < 100; i++) {
list.add("第" + i + "个item");
}
RepeatAdapter repeatAdapter = new RepeatAdapter(list, this);
rvRepeat.setLayoutManager(new LinearLayoutManager(this));
rvRepeat.setAdapter(repeatAdapter);
当我们滑动时,log如下:
可以看到,总共执行了7次onCreateViewHolder
,也就是说,总共100个item,只创建了7个viewholder
(篇幅问题,没有截到100,有兴趣的同学可以自己试试)
WHY?
通过阅读源码,我们发现,RecyclerView
的缓存单位是viewholder
,而获取viewholder
最终调用的方法是Recycler#tryGetViewHolderForPositionByDeadline
源码如下: