封装Recyclerview,使用起来超级方便

每次写recyclerview的时候需要写很多的代码,因此对其进行封装,调用的时候两三行代码搞定。

目录

1.封装一下adapter,创建第一个类CommonAdapter

2.封装Recyclerview,创建第二个类CustomRecyclerView

3.创建第三个类BaseViewHolder

4.使用方法

4.1 创建视图持有者viewholder

4.2 使用封装好的RecyclerView


1.封装一下adapter,创建第一个类CommonAdapter

该类扩展了 RecyclerView.Adapter,并使用泛型支持不同的数据类型和视图持有者。

/**
 *    desc   : 用来配合自定义的recyclerview使用
 */
public class CommonAdapter<T,VH extends BaseViewHolder<T>> extends  RecyclerView.Adapter<VH> {

    private List<T> dataList;
    private int layoutId;
    private BindData<T, VH> bindData;
    private ViewHolderFactory<VH> viewHolderFactory;  // 工厂用于创建 VH 实例

    public CommonAdapter(List<T> dataList, int layoutId, BindData<T, VH> bindData,ViewHolderFactory<VH> factory) {
        this.dataList = dataList;
        this.layoutId = layoutId;
        this.bindData = bindData;
        this.viewHolderFactory = factory;  // 传入工厂实例
    }

    // 更新数据的方法
    @SuppressLint("NotifyDataSetChanged")
    public void updateDataList(List<T> newDataList) {
        this.dataList = newDataList;
        notifyDataSetChanged();  // 通知RecyclerView数据已更新
    }
    @Override
    public VH onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
        return viewHolderFactory.createViewHolder(view);  // 使用工厂方法创建 VH
    }

    @Override
    public void onBindViewHolder(@NonNull VH holder, int position) {
        // 通过泛型绑定数据
        bindData.onBind(holder, dataList.get(position), position);
    }


    @Override
    public int getItemCount() {
        if (dataList==null)
        {
            return 0;
        }
        return dataList.size();
    }

    // 数据绑定回调接口
    public interface BindData<T, VH> {
        void onBind(VH holder, T data, int position);
    }
    // ViewHolder 工厂接口
    public interface ViewHolderFactory<VH> {
        VH createViewHolder(View view);
    }
}

构造函数的参数:

  • dataList:要显示的数据列表。
  • layoutId:每个项的布局资源 ID。
  • bindData:一个回调接口,用于将数据绑定到视图持有者。
  • factory:一个工厂接口,用于创建视图持有者实例。

关键方法:

  • updateDataList(List<T> newDataList):更新数据列表,并通知 RecyclerView 数据已更改。
  • onCreateViewHolder(ViewGroup parent, int viewType):创建新的视图持有者。
  • onBindViewHolder(@NonNull VH holder, int position):将数据绑定到视图持有者。
  • getItemCount():返回数据列表中的项总数。

2.封装Recyclerview,创建第二个类CustomRecyclerView

该类提供了一个方便的包装器,用于简化 RecyclerView 的设置和使用。


/**
 *    desc   : 自定义封装的Recyclerview 使用方便
 */
public class CustomRecyclerView {

    private RecyclerView recyclerView;
    private Context context;
    private RecyclerView.Adapter<?> adapter; // 将adapter变为全局变量

    public CustomRecyclerView(RecyclerView recyclerView, Context context) {
        this.recyclerView = recyclerView;
        this.context = context;
    }

    // 设置RecyclerView的Adapter
    public <T, VH extends BaseViewHolder<T>> void setAdapter(List<T> dataList, int layoutId,
                                                             CommonAdapter.BindData<T, VH> bindData, CommonAdapter.ViewHolderFactory<VH> factory) {
        adapter = new CommonAdapter<>(dataList, layoutId, bindData, factory); // 保存为全局变量
        recyclerView.setLayoutManager(new LinearLayoutManager(context));
        recyclerView.setAdapter(adapter);
    }

    // 支持GridLayoutManager
    public <T, VH extends BaseViewHolder<T>> void setGridAdapter(List<T> dataList, int layoutId, int spanCount,
                                                                 CommonAdapter.BindData<T, VH> bindData, CommonAdapter.ViewHolderFactory<VH> factory) {
        adapter = new CommonAdapter<>(dataList, layoutId, bindData, factory); // 保存为全局变量
        recyclerView.setLayoutManager(new GridLayoutManager(context, spanCount));
        recyclerView.setAdapter(adapter);
    }

    // 更新适配器数据的方法
    public <T> void updateAdapterData(List<T> newDataList) {
        if (adapter instanceof CommonAdapter) {
            ((CommonAdapter<T, ?>) adapter).updateDataList(newDataList);
        }
    }
}

构造函数的参数:

  • recyclerView:要管理的 RecyclerView 实例。
  • context:应用程序上下文。

关键方法:

  • setAdapter(...):为 RecyclerView 设置适配器,使用线性布局。
  • setGridAdapter(...):为 RecyclerView 设置适配器,使用网格布局。
  • updateAdapterData(List<T> newDataList):如果适配器是 CommonAdapter 的实例,则更新适配器中的数据。

3.创建第三个类BaseViewHolder

该类作为适配器的基础视图持有者。

public class BaseViewHolder<T> extends RecyclerView.ViewHolder {
    public T data;

    public BaseViewHolder(View itemView) {
        super(itemView);
    }
    public void bind(T data) {
        // 在这里实现数据绑定逻辑
    }
}

4.使用方法

创建完上面三个类之后,已经完成了对Recyclerview的封装

4.1 创建视图持有者viewholder

我们通过扩展 BaseViewHolder 并重写 bind() 方法实现视图持有者,处理数据绑定。

例如:
 

public class MyViewHolder extends BaseViewHolder<MyDataType> {
    TextView sceneName;
    public MyViewHolder(View itemView) {
        super(itemView);
        // 在ViewHolder中缓存控件
        sceneName = itemView.findViewById(R.id.name);
    }

    @Override
    public void bind(MyDataType data) {
        // 实现数据绑定逻辑
        if(data!=null)
        {
            sceneName.setText(data.getname)
        }
    }
}

4.2 使用封装好的RecyclerView

举个例子:

public class MyFragment extends Fragment {
    private RecyclerView recyclerView;
    private CustomRecyclerView customRecyclerView;
    private List<MyDataType> dataList; // 你的数据类型

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_my, container, false);
        recyclerView = view.findViewById(R.id.my_recycler_view);
        
        // 初始化数据列表
        dataList = new ArrayList<>();
        // 填充数据到 dataList...

        // 创建 CustomRecyclerView 实例并设置适配器
        customRecyclerView = new CustomRecyclerView(recyclerView, getContext());
        customRecyclerView.setGridAdapter(
                dataList,
                R.layout.item_rv,
                2,
                (holder, data, position) -> {
                    // 绑定数据的逻辑
                    holder.bind(data);
                },
                MyViewHolder::new
        );

        return view;
    }

    // 其他方法...
}

关键方法是这段:
 

 customRecyclerView = new CustomRecyclerView(recyclerView, getContext());
        customRecyclerView.setGridAdapter(
                dataList,
                R.layout.item_rv,
                2,
                (holder, data, position) -> {
                    // 绑定数据的逻辑
                    holder.bind(data);
                },
                MyViewHolder::new
        );

关键参数:

  • dataList:

    • 这是一个列表,包含要在 RecyclerView 中显示的数据项。数据的类型应与适配器所需的类型相匹配(例如,List<MyDataType>)。
    • dataList 中的每一项将会被传递到适配器中并显示在 RecyclerView 的每一行。
  • R.layout.item_rv:

    • 这是一个布局资源 ID,表示每个数据项在 RecyclerView 中的布局样式。对应着没封装的收viewHolder适配的那个XML 文件,定义了如何呈现每个项的视图。
    • item_rv 是你定义的布局文件名称,确保该文件存在于 res/layout 目录中。
  • 2:

    • 这个参数表示网格布局的列数。在这个例子中,每一行将会有两个列。这样设置后,RecyclerView 将会以网格的形式展示数据项。
  • (holder, data, position) -> { ... }:

    • 这是一个 Lambda 表达式,实现了 CommonAdapter.BindData 接口中的 onBind 方法。这个方法用于定义如何将数据绑定到视图持有者(ViewHolder)上。
    • 参数解释
      • holder:这是 ViewHolder 实例,代表当前正在显示的数据项的视图持有者。
      • data:当前项的数据(例如,dataList 中的一个元素)。
      • position:当前项在列表中的位置(索引)。
    • 在这个 Lambda 表达式中,调用了 holder.bind(data);,将数据传递给 ViewHolder,执行绑定逻辑。
  • SceneViewHolder::new:

    • 这是一个方法引用,用于创建 SceneViewHolder 实例。
    • SceneViewHolder 是一个自定义的 ViewHolder 类,扩展了 BaseViewHolder,用于处理特定数据类型的视图。在这里,new 关键字表示调用 SceneViewHolder 的构造函数来创建新实例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值