recyclerView如果走缓存的话就不走create方法
如果走scrap缓存的话,就不走bind
一、缓存原理
1.,RecyclerView会根据滑动的方向和位置,优先从mAttachedScrap中查找匹配的ViewHolder
mAttachedScrap:
①对应当前屏幕中可见的视图(ViewHolder)。
②数据结构为ArrayList,在LayoutManager#onLayoutChildren方法中对视图进行布局时,会将RecyclerView上的Views全部暂存到该集合中。
③如果缓存中的ViewHolder与RecyclerView上的position或itemId匹配,则视为“干净的ViewHolder”,可以直接使用,无需调用onBindViewHolder方法。
2.如果找不到,则进一步在mCachedViews中查找。
mCachedViews:
①缓存的是即将与RecyclerView分离的ViewHolder,即刚刚移出屏幕的Item。
②默认大小为2个(DEFAULT_CACHE_SIZE = 2)。
③缓存中的Item匹配后可以直接展示。
3.如果mCachedViews中也没有
mCachedViews:
①允许开发者自定义缓存。
②通过type和position来查找缓存
4.则会在RecycledViewPool中查找
RecycledViewPool:
①ViewHolder缓存池,可以支持不同的ViewType。
②默认的缓存数量是5个。
③优先级没有mCachedViews高,同时缓存中的Item需要再次调用onBindViewHolder()方法。
5.只有当所有缓存中都找不到匹配的ViewHolder时,才会通过Adapter的onCreateViewHolder方法重新创建一个新的ViewHolder。
在RecyclerView的缓存机制中,主要触发的方法包括:
onBindViewHolder(ViewGroup parent, int viewType):用于创建新的 ViewHolder 实例
当需要从缓存中取出ViewHolder并为其绑定数据时,会调用此方法。但需要注意的是,对于mAttachedScrap中的ViewHolder,由于它们是“干净的ViewHolder”,因此无需再次调用onBindViewHolder方法。
onCreateViewHolder(ViewHolder holder, int position): 将数据绑定到 ViewHolder 对应的视图上
当所有缓存中都无法找到匹配的ViewHolder时,会调用Adapter的此方法来创建一个新的ViewHolder。
二、适配器模式
Adapter:将数据转换为视图,并在数据发生变化时更新视图。
ViewHolder:用于缓存和复用视图对象,提高列表滚动时的性能。
自定义多种viewHolder:
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType){
case TYPE_BANNER:
return new BannerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.home_banner_layout,null));
case TYPE_AD:
return new BannerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.home_ad_item_layout,null));
case TYPE_TEXT:
return new BannerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.home_text_item_layout,null));
case TYPE_IMAGE:
return new BannerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.home_image_item_layout,null));
case TYPE_NEW:
return new BannerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.home_news_item_layout,null));
}
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
int type = getItemViewType(position);
switch (type){
case TYPE_BANNER:
// banner 逻辑处理
break;
case TYPE_AD:
// 广告逻辑处理
break;
case TYPE_TEXT:
// 文本逻辑处理
break;
case TYPE_IMAGE:
//图片逻辑处理
break;
case TYPE_NEW:
//视频逻辑处理
break;
// ... 此处省去N行代码
}
}
三、添加listener
1.添加简单listener
自定义listener接口
在Activity/fragment中adapter.setListener(),将listener传给adapter
在adapter的bindviewHolder时候调用holder.setListener(),将listener传给holder
在holder中调用listener的方法
2.添加拖动删除listener
创建一个ItemTouchHelper.Callback的实现类。
重写onMove方法,使得拖动操作无效(通常不需要拖动功能)。
重写onSwiped方法,以便在项目被滑动时执行删除操作。
创建ItemTouchHelper的实例,并将其与RecyclerView关联。
public class SwipeToDeleteCallback extends ItemTouchHelper.Callback {
private final ItemTouchHelperAdapter adapter;
public SwipeToDeleteCallback(ItemTouchHelperAdapter adapter) {
this.adapter = adapter;
}
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
// 不允许拖动
int dragFlags = 0;
// 允许向右滑动
int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
return makeMovementFlags(dragFlags, swipeFlags);
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
return false; // 不支持拖动
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
// 删除被滑动的item
adapter.deleteItem(viewHolder.getAdapterPosition());
}
@Override
public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
// 可以在这里自定义滑动后item的UI变化
}
}
// 在Activity或Fragment中
ItemTouchHelper.Callback callback = new SwipeToDeleteCallback(yourAdapter);
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(callback);
itemTouchHelper.attachToRecyclerView(yourRecyclerView);
// 你的Adapter需要实现ItemTouchHelperAdapter接口
public interface ItemTouchHelperAdapter {
void deleteItem(int position);
}