超好用Adapter封装使用

前言
在Android开发过程中,我们经常会用到adapter。因为adapter在基本使用的过程中,代码比较繁琐,于是进行一个简单封装,使调用起来更加简单便捷。这节就来讲讲这个适配器的封装吧。
今天涉及的内容:

  1. adapter库依赖
  2. 封装类ComAdapter和GroupAdapter概述
  3. 通用适配器ComAdapter的使用
  4. 分组适配器GroupAdapter的使用
  5. MainActivity中调用示例
  6. 效果图和项目结构图
先来波adapter使用的效果图吧

超好用Adapter封装使用
文章图片
1.gif 一. adapter库依赖 本adapter的封装是建立在一个第三方库的基础之上的。在使用之前,你需要添加该库的依赖:
在project对应的build.gradle中添加maven依赖:
allprojects { repositories { google() jcenter() maven { url 'https://jitpack.io' } } }

在app_model对应的build.gradle中添加该库引用:
//Brvah(adapter)适配器 implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.34'

二.封装类ComAdapter和GroupAdapter概述 【超好用Adapter封装使用】适配器库BaseRecyclerViewAdapterHelper是一个专注adapter的库,里面有一个适配器基类:BaseQuickAdapter,为了方便日常调度使用,我在BaseQuickAdapter基础上再度扩展,分别整合了两个adapter基类:ComAdapter和GroupAdapter。
ComAdapter:基于一般的列表或九宫格布局的使用
GroupAdapter:基于简单的分组列表展示使用。
三.通用适配器ComAdapter的使用 ComAdapter是一个通用适配器基类,里面集成了adapter创建需要的一些基本方法,包括控件初始化,获取布局对象,加载动画,列表数据加载,控件点击事件监听等方法。 当你要实现一个线性列表,需要创建adapter的时候,继承ComAdapter可以帮你快速实现自己的adapter。
3.1 继承ComAdapter,写自己的Adapter 当RecyclerView加载列表的时候,需要一个适配器(NameAdapter),你可以像这样快速来创建它:
public class NameAdapterextends ComAdapter {private TextView mTvName; public NameAdapter(List data, Context context) { //加载布局和数据 super(R.layout.item_layout, data, context); }@Override public void initView(BaseViewHolder viewHolder, T obj) { //控件初始化 mTvName=viewHolder.getView(R.id.tv); }@Override public void initData(BaseViewHolder viewHolder, T obj) { String name=obj.toString(); mTvName.setText(name); }@Override public void setListener(BaseViewHolder viewHolder, T obj) { //添加控件监听 addOnClickListener(mTvName,viewHolder,obj); }}

3.2 线性布局调用
mNames=new ArrayList<>(); //for (int i = 0; i < 10; i++) { //mNames.add("小黄"+i); //} mNameAdapter=new NameAdapter<>(mNames,MainActivity.this); mNameAdapter.setRecyclerLinearManager(mRecyclerView);

3.3 九宫格布局调用
mNames=new ArrayList<>(); //for (int i = 0; i < 10; i++) { //mNames.add("小黄"+i); //} mNameAdapter=new NameAdapter<>(mNames,MainActivity.this); mNameAdapter.setRecyclerGridManager(mRecyclerView,4);

3.4 设置分割线,返回RecyclerView.ItemDecoration对象
//设置线性布局分割线 LinearDividerItemDecoration linearDivider=mNameAdapter.setLinearLayoutItemSpace(mRecyclerView,5,R.color.colorAccent); //设置九宫格局分割线 GridDividerItemDecoration gridDivider=mNameAdapter.setGridLayoutItemSpace(mRecyclerView,5,R.color.colorAccent);

3.5 移除分割线
/**移除RecycleView间距**/ removeItemSpace(RecyclerView recyclerView,RecyclerView.ItemDecoration divider)

3.6 点击事件
//点击事件 mNameAdapter.setOnItemClickListener(new AdapterHelper.OnItemClickListener() { @Override public void itemClickListener(View view, BaseViewHolder viewHolder, Object obj) { switch (view.getId()) { case R.id.tv: ToastUtil.shortShow("====1====="+obj.toString()); break; default: break; } } });

四. 分组适配器GroupAdapter的使用 GroupAdapter是一个列表分组显示的适配器基类,里面集成了adapter创建需要的一些基本方法,包括控件初始化,获取布局对象,加载动画,列表数据加载,控件点击事件监听等方法。 当你要船创建一个分组显示功能的adapter,继承GroupAdapter可方便快捷实现
4.1 javaBean继承SectionEntity类 GroupAdapter显示的数据,都需要用javaBean进行封装。并且JavaBean需要继承SectionEntity类,然后重写含(boolean isHeader, String header)参数的构造方法。 以Person对象为例,你需要这样处理:
public class Person extends SectionEntity {private String name; private int age; public Person(boolean isHeader, String header) { super(isHeader,header); }public String getName() { return name; }public void setName(String name) { this.name = name; }public int getAge() { return age; }public void setAge(int age) { this.age = age; }@Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }

4.2 继承GroupAdapter,写自己的adapter 然后写一个自己的adapter,继承自GroupAdapter,以PersonAdapter为例:
public class PersonAdapter extends GroupAdapter {//header private TextView mTvHeader; //item private TextView mTvItem; public PersonAdapter(List data, Context context) { super(R.layout.item_layout, R.layout.header_layout, data,context); }@Override protected void convertHead(BaseViewHolder viewHolder, SectionEntity item) { //标题相关所有都在此处理 //标题初始化 mTvHeader=viewHolder.getView(R.id.tv_title); //标题数据处理 mTvHeader.setText(item.header); //标题点击事件 addOnClickListener(mTvHeader,viewHolder,item); }@Override public void initView(BaseViewHolder viewHolder, T obj) { //item初始化 mTvItem=viewHolder.getView(R.id.tv); }@Override public void initData(BaseViewHolder viewHolder, T obj) { //item数据处理 Person person= (Person) obj; mTvItem.setText("姓名:"+person.getName()+"年龄:"+person.getAge()); }@Override public void setListener(BaseViewHolder viewHolder, T obj) { //item中控件监听 addOnClickListener(mTvItem,viewHolder,obj); } }

其中PersonAdapter(List data, Context context)构造方法的super方法中,要引入两个布局id,一个是item的一个是header的。 Header相关方法都在convertHead中处理。item的相关处理在initView,initData和setListener方法中进行。
4.3 线性布局使用
mPersonList=new ArrayList<>(); //for (int i = 0; i < 10; i++) { //Person person; //if(i%7==0){//header //person=new Person(true,"标题"+i); //}else{//item //person=new Person(false,null); //person.setName("小黑"+i); //person.setAge(25+i); // } //mPersonList.add(person); //} mPersonAdapter=new PersonAdapter<>(mPersonList,MainActivity.this); mPersonAdapter.setRecyclerLinearManager(mRecyclerView);

4.4 九宫格布局使用
mPersonList=new ArrayList<>(); //for (int i = 0; i < 10; i++) { //Person person; //if(i%7==0){//header //person=new Person(true,"标题"+i); //}else{//item //person=new Person(false,null); //person.setName("小黑"+i); //person.setAge(25+i); // } //mPersonList.add(person); //} mPersonAdapter=new PersonAdapter<>(mPersonList,MainActivity.this); mPersonAdapter.setRecyclerGridManager(mRecyclerView,3);

4.5 设置分割线,返回RecyclerView.ItemDecoration对象 线性布局的时候,可以像下面这样设置分割线:
//线性布局分割线 LinearDividerItemDecoration linearDivider=mPersonAdapter.setLinearLayoutItemSpace(mRecyclerView, 5, R.color.colorAccent);

注意: 在实现分组适配器<即继承GroupAdapter的adapter>不能使用setGridLayoutItemSpace给列表设置分割线,会出现ui上显示的bug,为了避免 用户使用不当,我已经将GroupAdapter类中的setGridLayoutItemSpace抛出异常并做以错误提示。大家若还是需要在分组九宫格布局中做分割线的话, 需要自己在布局中,或者在adapter中处理数据的时候,用代码来实现分割线效果。
4.6 移除分割线
/**移除RecycleView间距**/ removeItemSpace(RecyclerView recyclerView, RecyclerView.ItemDecoration divider)

4.7 点击事件 若要设置adapter的点击事件,你可以像下面这样写:
//点击事件 mPersonAdapter.setOnItemClickListener(new AdapterHelper.OnItemClickListener() { @Override public void itemClickListener(View view, BaseViewHolder viewHolder, Object obj) { Person person= (Person) obj; switch (view.getId()) { case R.id.tv_title://header ToastUtil.shortShow("===="+person.header+"==="); break; case R.id.tv://item ToastUtil.shortShow("===="+person.getName()+"==="); break; default: break; } } });

五.MainActivity中调用示例 下面贴出adapter在MainActivity中使用的代码:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {private Button mBtn1; private Button mBtn2; private Button mBtn3; private Button mBtn4; private RecyclerView mRecyclerView; private ListmNames; private NameAdaptermNameAdapter; private ListmPersonList; private PersonAdaptermPersonAdapter; private LinearDividerItemDecoration mLinearDivider; private GridDividerItemDecoration mGridDivider; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initData(); setListener(); }private void initData() { mBtn1 = findViewById(R.id.btn1); mBtn2 = findViewById(R.id.btn2); mBtn3 = findViewById(R.id.btn3); mBtn4 = findViewById(R.id.btn4); mRecyclerView = findViewById(R.id.rv); mBtn1.setText("通用线性"); mBtn2.setText("通用九宫"); mBtn3.setText("分组线性"); mBtn4.setText("分组九宫"); }private void setListener() { mBtn1.setOnClickListener(this); mBtn2.setOnClickListener(this); mBtn3.setOnClickListener(this); mBtn4.setOnClickListener(this); }@Override public void onClick(View v) { switch (v.getId()) { case R.id.btn1://通用布局线性测试 commonLinearLayout(); break; case R.id.btn2://通用布局九宫格测试 commonGridLayout(); break; case R.id.btn3://分组布局线性测试 diffGropLinearLayout(); break; case R.id.btn4://分组布局九宫格测试 diffGropGridLayout(); break; default: break; } //点击事件 commonDiffClick(); }private void initCommonData(){ //通用布局 if(mNames==null) { mNames = new ArrayList<>(); } mNames.clear(); for (int i = 0; i < 10; i++) { mNames.add("小黄" + i); } }private void initdiffGropData(){ //分组布局 if(mPersonList==null) { mPersonList = new ArrayList<>(); } mPersonList.clear(); for (int i = 0; i < 10; i++) { Person person; if(i%7==0){//header person=new Person(true,"标题"+i); }else{//item person=new Person(false,null); person.setName("小黑"+i); person.setAge(25+i); } mPersonList.add(person); }}/** * 通用布局线性测试 **/ private void commonLinearLayout() { initCommonData(); mNameAdapter = new NameAdapter<>(mNames, MainActivity.this); mNameAdapter.setRecyclerLinearManager(mRecyclerView); //清除旧的分割线 mNameAdapter.removeItemSpace(mRecyclerView,mLinearDivider); mNameAdapter.removeItemSpace(mRecyclerView,mGridDivider); //设置分割线 mLinearDivider=mNameAdapter.setLinearLayoutItemSpace(mRecyclerView, 5, R.color.colorAccent); }/** * 通用布局九宫格测试 **/ private void commonGridLayout() { initCommonData(); mNameAdapter = new NameAdapter<>(mNames, MainActivity.this); mNameAdapter.setRecyclerGridManager(mRecyclerView, 3); //清除旧的分割线 mNameAdapter.removeItemSpace(mRecyclerView,mLinearDivider); mNameAdapter.removeItemSpace(mRecyclerView,mGridDivider); //设置分割线 mGridDivider=mNameAdapter.setGridLayoutItemSpace(mRecyclerView, 5, R.color.colorAccent); }/** * 分组布局线性测试 **/ private void diffGropLinearLayout() { initdiffGropData(); mPersonAdapter=new PersonAdapter<>(mPersonList,MainActivity.this); mPersonAdapter.setRecyclerLinearManager(mRecyclerView); //清除旧的分割线 mNameAdapter.removeItemSpace(mRecyclerView,mLinearDivider); mNameAdapter.removeItemSpace(mRecyclerView,mGridDivider); //设置分割线 mLinearDivider=mPersonAdapter.setLinearLayoutItemSpace(mRecyclerView, 5, R.color.colorAccent); }/** * 分组布局九宫格测试 **/ private void diffGropGridLayout() { initdiffGropData(); mPersonAdapter=new PersonAdapter<>(mPersonList,MainActivity.this); mPersonAdapter.setRecyclerGridManager(mRecyclerView,3); //清除旧的分割线 mNameAdapter.removeItemSpace(mRecyclerView,mLinearDivider); mNameAdapter.removeItemSpace(mRecyclerView,mGridDivider); }/**点击事件**/ private void commonDiffClick(){ //通用布局点击事件 if(mNameAdapter!=null) { mNameAdapter.setOnItemClickListener(new AdapterHelper.OnItemClickListener() { @Override public void itemClickListener(View view, BaseViewHolder viewHolder, Object obj) { switch (view.getId()) { case R.id.tv: ToastUtil.shortShow("====1=====" + obj.toString()); break; default: break; } } }); }//分组布局点击事件 if(mPersonAdapter!=null) { mPersonAdapter.setOnItemClickListener(new AdapterHelper.OnItemClickListener() { @Override public void itemClickListener(View view, BaseViewHolder viewHolder, Object obj) { Person person = (Person) obj; switch (view.getId()) { case R.id.tv_title://header ToastUtil.shortShow("====" + person.header + "==="); break; case R.id.tv://item ToastUtil.shortShow("====" + person.getName() + "==="); break; default: break; } } }); } }}

六. 效果图和项目结构图 效果图

超好用Adapter封装使用
文章图片
1.gif
项目结构图

超好用Adapter封装使用
文章图片
image.png

    推荐阅读