RecyclerView缓存及其原理

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);
}

3.添加动画

四、一些功能优点

1.itemdecoration
2.支持多种布局
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值