每次写recyclerview的时候需要写很多的代码,因此对其进行封装,调用的时候两三行代码搞定。
目录
1.封装一下adapter,创建第一个类CommonAdapter
2.封装Recyclerview,创建第二个类CustomRecyclerView
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
目录中。
- 这是一个布局资源 ID,表示每个数据项在
-
2
:- 这个参数表示网格布局的列数。在这个例子中,每一行将会有两个列。这样设置后,
RecyclerView
将会以网格的形式展示数据项。
- 这个参数表示网格布局的列数。在这个例子中,每一行将会有两个列。这样设置后,
-
(holder, data, position) -> { ... }
:- 这是一个 Lambda 表达式,实现了
CommonAdapter.BindData
接口中的onBind
方法。这个方法用于定义如何将数据绑定到视图持有者(ViewHolder
)上。 - 参数解释:
holder
:这是ViewHolder
实例,代表当前正在显示的数据项的视图持有者。data
:当前项的数据(例如,dataList
中的一个元素)。position
:当前项在列表中的位置(索引)。
- 在这个 Lambda 表达式中,调用了
holder.bind(data);
,将数据传递给ViewHolder
,执行绑定逻辑。
- 这是一个 Lambda 表达式,实现了
-
SceneViewHolder::new
:- 这是一个方法引用,用于创建
SceneViewHolder
实例。 SceneViewHolder
是一个自定义的ViewHolder
类,扩展了BaseViewHolder
,用于处理特定数据类型的视图。在这里,new
关键字表示调用SceneViewHolder
的构造函数来创建新实例。
- 这是一个方法引用,用于创建