一、框架引入

  • 先在项目的 build.gradle(Project:XXXX) 的 repositories 添加:
    allprojects {repositories {...maven { url "https://jitpack.io" }}}
  • 然后在Module的 build.gradle(Module:app) 的 dependencies 添加:
    dependencies {......compile 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.22'}

2.2 最基本使用示例Demo

  • 要是刚接触Android的朋友要是还是不知道怎么用,那我这里提供一个很简单的demo:

  • 比如说我想要实现的效果大致如下:

  • 第一步:在布局文件中引入RecyclerView
    activity_main.xml

  • <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><android.support.v7.widget.RecyclerViewandroid:id="@+id/recycler_view"android:layout_width="match_parent"android:layout_height="wrap_content" />
    </RelativeLayout>
    
  • 第二步:编写条目布局文件
    item_rv.xml(省略)
  • 第三步:编写数据实体类型
    Model.java
public class Model {private String title;private String content;private String imgUrl;//生成set、get方法......
}
  • 第四步:编写适配器
    MyAdapter.java
public class MyAdapter extends BaseQuickAdapter<Model, BaseViewHolder> {public MyAdapter(@LayoutRes int layoutResId, @Nullable List<Model> data) {super(layoutResId, data);}@Overrideprotected void convert(BaseViewHolder helper, Model item) {//可链式调用赋值helper.setText(R.id.tv_title, item.getTitle()).setText(R.id.tv_content, item.getContent()).setImageResource(R.id.iv_img, R.mipmap.ic_launcher);//获取当前条目position//int position = helper.getLayoutPosition();}
}
  • 最后一步:在Activity中使用该适配器
    MainActivity.java
public class MainActivity extends AppCompatActivity {private RecyclerView recyclerView;private List<Model> datas;private MyAdapter adapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//初始化RecyclerViewrecyclerView = (RecyclerView) findViewById(R.id.recycler_view);//模拟的数据(实际开发中一般是从网络获取的)datas = new ArrayList<>();Model model;for (int i = 0; i < 15; i++) {model = new Model();model.setTitle("我是第" + i + "条标题");model.setContent("第" + i + "条内容");datas.add(model);}//创建布局管理LinearLayoutManager layoutManager = new LinearLayoutManager(this);layoutManager.setOrientation(LinearLayoutManager.VERTICAL);recyclerView.setLayoutManager(layoutManager);//创建适配器adapter = new MyAdapter(R.layout.item_rv, datas);//给RecyclerView设置适配器recyclerView.setAdapter(adapter);}
}
  • OK,运行,得到的效果就是上述的效果。

三、点击事件

  • 上文中描述的就是使用BaseRecyclerViewAdapterHelper最基本的用法,因为怕刚接触Android的兄弟们不明朗或不相信这么简单的用法,所以做了上节简单的demo示例用法。

  • 那么使用列表当然少不了点击事件,不论是整个条目的点击事件还是条目中子控件的点击事件,该适配器对点击事件也是做了及简化的处理:

3.1 条目事件

Item的点击事件

        //条目点击事件adapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {@Overridepublic void onItemClick(BaseQuickAdapter adapter, View view, int position) {Toast.makeText(MainActivity.this, "点击了第" + (position + 1) + "条条目", Toast.LENGTH_SHORT).show();}});

Item的长按事件

        //条目长按事件adapter.setOnItemLongClickListener(new BaseQuickAdapter.OnItemLongClickListener() {@Overridepublic boolean onItemLongClick(BaseQuickAdapter adapter, View view, int position) {Toast.makeText(MainActivity.this, "长按了第" + (position + 1) + "条条目", Toast.LENGTH_SHORT).show();return false;}});

注意事项

  • 在嵌套recycleView的情况下需要使用你使用 adapter. setOnItemClickListener 来设置点击事件,如果使用recycleView.addOnItemTouchListener会累计添加的。

3.2 条目子控件事件

Item子控件的点击事件

  • 首先:在adapter的convert方法里面通过 helper.addOnClickListener 绑定一下子控件的控件id
    @Overrideprotected void convert(BaseViewHolder helper, Model item) {//可链式调用赋值helper.setText(R.id.tv_title, item.getTitle()).setText(R.id.tv_content, item.getContent()).addOnClickListener(R.id.iv_img)    //给图标添加点击事件.setImageResource(R.id.iv_img, R.mipmap.ic_launcher);//获取当前条目position//int position = helper.getLayoutPosition();}
  • 然后:我们设置
        //条目子控件点击事件adapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {@Overridepublic void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {Toast.makeText(MainActivity.this, "点击了第" + (position + 1) + "条条目的图片", Toast.LENGTH_SHORT).show();}});

Item子控件的长按事件

  • 这里和子控件点击事件是一样的,只是将 点击 变成 长按 就可以了

  • 首先:在adapter的convert方法里面通过 helper.addOnLongClickListener 绑定一下子控件的控件id

    @Overrideprotected void convert(BaseViewHolder helper, Model item) {//可链式调用赋值helper.setText(R.id.tv_title, item.getTitle()).setText(R.id.tv_content, item.getContent())//.addOnClickListener(R.id.iv_img)    //给图标添加点击事件.addOnLongClickListener(R.id.iv_img)//给图片添加长按事件.setImageResource(R.id.iv_img, R.mipmap.ic_launcher);//获取当前条目position//int position = helper.getLayoutPosition();}
  • 然后:我们设置
        //条目子控件长按事件adapter.setOnItemChildLongClickListener(new BaseQuickAdapter.OnItemChildLongClickListener() {@Overridepublic boolean onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) {Toast.makeText(MainActivity.this, "长按了第" + (position + 1) + "条条目的图片", Toast.LENGTH_SHORT).show();return false;}});

注意事项

  • 设置子控件的事件,如果不在adapter中绑定,点击事件无法生效,因为无法找到你需要设置的控件。

多个Item子控件事件

  • 官方文档上没说,但是 其实这里可以用很常规的方法处理,就是通过判断ID来判定是否是我要的控件?,从而处理不同的事件

  • 比如我这里给 图片和标题 都加点击事件处理不同的逻辑

  • 首先:当然是在适配器中给图片和标题都添加点击事件

 @Overrideprotected void convert(BaseViewHolder helper, Model item) {//可链式调用赋值helper.setText(R.id.tv_title, item.getTitle()).setText(R.id.tv_content, item.getContent()).addOnClickListener(R.id.iv_img)    //给图标添加 点击事件.addOnClickListener(R.id.tv_title)  //给标题也添加 点击事件.setImageResource(R.id.iv_img, R.mipmap.ic_launcher);//获取当前条目position//int position = helper.getLayoutPosition();}
  • 其次:
        //条目子控件点击事件adapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {@Overridepublic void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {//判断idif (view.getId() == R.id.iv_img) {Log.i("tag", "点击了第" + position + "条条目的 图片");} else if (view.getId() == R.id.tv_title) {Log.i("tag", "点击了第" + position + "条条目的 标题");}}});
  • 那么如果是长按事件呢?当然也是相同的处理方法。

如果需要在子控件事件中获取其他子控件可以使用:

getViewByPosition(RecyclerView recyclerView, int position, @IdRes int viewId)

比如:

        //条目子控件点击事件adapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {@Overridepublic void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {Toast.makeText(MainActivity.this, "点击了第" + (position + 1) + "条条目的图片", Toast.LENGTH_SHORT).show();TextView tv_title = (TextView) adapter.getViewByPosition(recyclerView, position, R.id.tv_title);Log.i("tag", "当前图片对应的 title=" + tv_title.getText());}});//条目子控件长按事件adapter.setOnItemChildLongClickListener(new BaseQuickAdapter.OnItemChildLongClickListener() {@Overridepublic boolean onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) {Toast.makeText(MainActivity.this, "长按了第" + position + "条条目的图片", Toast.LENGTH_SHORT).show();TextView tv_title = (TextView) adapter.getViewByPosition(recyclerView, position, R.id.tv_title);Log.i("tag", "长按的图片对应的title=" + tv_title.getText());return false;}});

注意:如果有header的话需要处理一下position加上 headerlayoutcount。

  • 最后,到这里,点击事件基本就完了

五、添加头部、尾部

  • 添加
    (可以添加多个头部或尾部)
mQuickAdapter.addHeaderView(headerView);
mQuickAdapter.addFooterView(footerView);
  • 删除指定view
mQuickAdapter.removeHeaderView(headerView);
mQuickAdapter.removeFooterView(footerView);
  • 删除所有
mQuickAdapter.removeAllHeaderView();
mQuickAdapter.removeAllFooterView();
  • 默认出现了头部就不会显示Empty,和尾部,配置以下方法也支持同时显示:
mQuickAdapter.setHeaderAndEmpty()
mQuickAdapter.setHeaderFooterEmpty();
  • 默认头部尾部都是占满一行,如果需要不占满可以配置:
mQuickAdapter.setHeaderViewAsFlow();
mQuickAdapter.setFooterViewAsFlow();

六、上拉加载

  • 没错,该适配器居然还实现了加载更多的功能,真心佩服作者

  • 设置上拉加载

// 滑动最后一个Item的时候回调onLoadMoreRequested方法
setOnLoadMoreListener(RequestLoadMoreListener);
  • 默认第一次加载会进入回调,如果不需要可以配置:
mQuickAdapter.disableLoadMoreIfNotFullPage();
  • 回调处理代码
//上拉加载(设置这个监听就表示有上拉加载功能了)
mQuickAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {@Override public void onLoadMoreRequested() {mRecyclerView.postDelayed(new Runnable() {@Overridepublic void run() {if (mCurrentCounter >= TOTAL_COUNTER) {//数据全部加载完毕mQuickAdapter.loadMoreEnd();} else {if (isErr) {//成功获取更多数据(可以直接往适配器添加数据)mQuickAdapter.addData(DataServer.getSampleData(PAGE_SIZE));mCurrentCounter = mQuickAdapter.getData().size();//主动调用加载完成,停止加载mQuickAdapter.loadMoreComplete();} else {//获取更多数据失败isErr = true;Toast.makeText(PullToRefreshUseActivity.this, R.string.network_err, Toast.LENGTH_LONG).show();//同理,加载失败也要主动调用加载失败来停止加载(而且该方法会提示加载失败)mQuickAdapter.loadMoreFail();}}}}, delayMillis);}}, mReyclerView);
  • 加载完成(注意不是加载结束,而是本次数据加载结束并且还有下页数据)
mQuickAdapter.loadMoreComplete();
  • 加载失败
mQuickAdapter.loadMoreFail();
  • 加载结束
mQuickAdapter.loadMoreEnd();

注意:如果上拉结束后,下拉刷新需要再次开启上拉监听,需要使用setNewData方法填充数据。

  • 打开或关闭加载(一般用于下拉的时候做处理,因为上拉下拉不能同时操作)
mQuickAdapter.setEnableLoadMore(boolean);
  • 预加载(这个功能屌炸天)
// 当列表滑动到倒数第N个Item的时候(默认是1)回调onLoadMoreRequested方法
mQuickAdapter.setPreLoadNumber(int);

设置自定义加载布局

mQuickAdapter.setLoadMoreView(new CustomLoadMoreView());
public final class CustomLoadMoreView extends LoadMoreView {@Override public int getLayoutId() {return R.layout.view_load_more;}/*** 如果返回true,数据全部加载完毕后会隐藏加载更多* 如果返回false,数据全部加载完毕后会显示getLoadEndViewId()布局*/@Override public boolean isLoadEndGone() {return true;}@Override protected int getLoadingViewId() {return R.id.load_more_loading_view;}@Override protected int getLoadFailViewId() {return R.id.load_more_load_fail_view;}/*** isLoadEndGone()为true,可以返回0* isLoadEndGone()为false,不能返回0*/@Override protected int getLoadEndViewId() {return 0;}
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="@dimen/dp_40"><LinearLayoutandroid:id="@+id/load_more_loading_view"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="horizontal"><ProgressBarandroid:id="@+id/loading_progress"android:layout_width="wrap_content"android:layout_height="wrap_content"style="?android:attr/progressBarStyleSmall"android:layout_marginRight="@dimen/dp_4"android:indeterminateDrawable="@drawable/sample_footer_loading_progress"/><TextViewandroid:id="@+id/loading_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="@dimen/dp_4"android:text="@string/loading"android:textColor="#0dddb8"android:textSize="@dimen/sp_14"/></LinearLayout><FrameLayoutandroid:id="@+id/load_more_load_fail_view"android:layout_width="match_parent"android:layout_height="match_parent"android:visibility="gone"><TextViewandroid:id="@+id/tv_prompt"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:textColor="#0dddb8"android:text="@string/load_failed"/></FrameLayout></FrameLayout>

九、多布局

  • 多种类型条目的列表是我们日常开发中非常常见的功能,当然该适配器也给我们提供了相应的方法。

  • 使用该适配器设置不同类型条目有两种方式,一种 耦合了实体类,一种是设置代理,这里两种方式我都会演示一遍。

Demo实例演示

  • 从上述文档中我们是可以看出来两点

1.我们的数据不直接传给适配器,而是通过MultiItemEntity来传递
2.适配器构造里必须绑定type和layout的关系

  • 废话不多说,演示一个小demo(这里Item布局我就不贴出来了)

第一步:创建MultiItemEntity类

public class MyMultipleItem implements MultiItemEntity {public static final int FIRST_TYPE = 1;public static final int SECOND_TYPE = 2;public static final int NORMAL_TYPE = 3;private int itemType;private Model data;public MyMultipleItem(int itemType, Model data) {this.itemType = itemType;this.data = data;}@Overridepublic int getItemType() {return itemType;}public Model getData(){return data;}
}

第二步:创建适配器

public class MultipleItemAdapter extends BaseMultiItemQuickAdapter<MyMultipleItem, BaseViewHolder> {public MultipleItemAdapter(List data) {super(data);//必须绑定type和layout的关系addItemType(MyMultipleItem.FIRST_TYPE, R.layout.first_type_layout);addItemType(MyMultipleItem.SECOND_TYPE, R.layout.second_type_layout);addItemType(MyMultipleItem.NORMAL_TYPE, R.layout.item_rv);}@Overrideprotected void convert(BaseViewHolder helper, MyMultipleItem item) {switch (helper.getItemViewType()) {case MyMultipleItem.FIRST_TYPE:Log.i("tag","FIRST_TYPE==============="+helper.getLayoutPosition());break;case MyMultipleItem.SECOND_TYPE:Log.i("tag","SECOND_TYPE==============="+helper.getLayoutPosition());break;case MyMultipleItem.NORMAL_TYPE:helper.setImageResource(R.id.iv_img, R.mipmap.ic_launcher).setText(R.id.tv_title, item.getData().getTitle()).setText(R.id.tv_content, item.getData().getContent());break;}}
}

第三步:最后当然是在我们的Activity里编写代码

public class MainActivity extends AppCompatActivity {private RecyclerView recyclerView;private List<Model> datas01;private List<MyMultipleItem> datas02;private MultipleItemAdapter adapter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//初始化RecyclerViewrecyclerView = (RecyclerView) findViewById(R.id.recycler_view);//模拟的假数据(实际开发中当然是从网络获取数据)datas01 = new ArrayList<>();Model model;for (int i = 0; i < 30; i++) {model = new Model();model.setTitle("我是第" + i + "条标题");model.setContent("第" + i + "条内容");datas01.add(model);}datas02 = new ArrayList<>();//这里我是随机给某一条目加载不同的布局for (int i = 0; i < 30; i++) {if (i % 3 == 0) {datas02.add(new MyMultipleItem(MyMultipleItem.FIRST_TYPE, null));} else if (i % 7 == 0) {datas02.add(new MyMultipleItem(MyMultipleItem.SECOND_TYPE, null));} else {datas02.add(new MyMultipleItem(MyMultipleItem.NORMAL_TYPE, datas01.get(i)));}}//创建布局管理LinearLayoutManager layoutManager = new LinearLayoutManager(this);layoutManager.setOrientation(LinearLayoutManager.VERTICAL);recyclerView.setLayoutManager(layoutManager);//创建适配器adapter = new MultipleItemAdapter(datas02);//给RecyclerView设置适配器recyclerView.setAdapter(adapter);}
}

作者:猜火车_
链接:https://www.jianshu.com/p/1e20f301272e
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

抄录整理:鹿人_甲

RecyclerView 万能适配器相关推荐

  1. RecyclerView万能全套大宝剑

    1.万能Adapter: package xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxximport android.content.Context import andro ...

  2. 第7天 Recyclerview万能的适配器(基本使用、分割线、增加删除动画)

    第7天 Recyclerview万能的适配器(基本使用.分割线.增加删除动画) Recyclerview的使用 思路 代码 Recyclerview的使用 用了很长一段时间的RecyclerView, ...

  3. day5 RecyclerView、多布局、万能适配器

    RecyclerView 概义 RecyclerView是什么 从Android 5.0开始,谷歌公司推出了一个用于大量数据展示的新控件RecylerView,可以用来代替传统的ListView,更加 ...

  4. Android BaseQuickAdapter万能适配器

    RecycleView万能适配器 一导入 implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.24' implem ...

  5. Android万能适配器BaseRecyclerViewAdapterHelper的简单使用

    继我们上一章的网络请求的封装中,我们在现有的项目中通过我们的万能适配器来写一个简单的Recyclerview列表 效果图 video1 首先还是同样的道理,我们需要进行一个简单的依赖添加 //recy ...

  6. Android 万能适配器BaseQuickAdapter操作及免费源码

    Android 万能适配器BaseQuickAdapter操作及免费源码,本篇巨长无比,非常详细的介绍了BaseQuickAdapter,若有帮助到您,记得点个赞哦~ 简介 导入依赖 简单使用 添加头 ...

  7. Android万能适配器BaseListAdapter

    我们在写列表的时候都要用到适配器Adapter,如果每一个列表都去创建一个Adapter以及相应的ViewHolder,则重复代码太多,效率低下,为了改变这种情况,我们需要做到尽可能多的复用Adapt ...

  8. Android进阶笔记09:Android 万能适配器

    1. Android 万能适配器      项目中Listview GridView几乎是必用的组件,Android也提供一套机制,为这些控件绑定数据,那就是Adapter.用起来虽然还不错,但每次都 ...

  9. RecyclerView复杂适配器的终极形态?代码更解耦

    本文已授权微信公众号:鸿洋  在微信公众号平台原创首发.RecyclerView复杂适配器的"终极形态"?代码更解耦 前言 RecyclerView是Android开发中很常用的控 ...

最新文章

  1. linux文件移出目录命令_Linux 文件与目录管理详解
  2. 为什么经营婚姻要像热恋一样
  3. 【正一专栏】钱都从哪里来的?
  4. 剑网三缘起应老玩家要求调整规则,几分钟就能搞定,获得足够声望
  5. python的进程和线程_Python进程与线程知识
  6. 拒绝做思想的巨人,行动上的矮子
  7. windows使用WSL安装linux子系统
  8. 2699元不加价!魅族16s Pro国家宝藏之越王勾践剑礼盒上架
  9. 花了10块钱,我在朋友圈成为了富豪...
  10. Spring MVC+MyBatis中Spring没有接管Mybatis的事务
  11. OpenStack-Icehouse(nova-network)多节点基础环境部署
  12. 09年关门歇业的15大网站 雅虎旗下4网站上榜
  13. 【KDD20】TAdaNet: 用于图增强元学习的任务自适应网络
  14. 树算法系列之一:CART回归树
  15. php 显示探针_PHP探针
  16. 入职Apifox研发组三个月,我领悟了30个高效开发方法
  17. 计算机系技能比赛黑板报,技能成就梦想黑板报图文
  18. iview在table中添加图片
  19. 塞规公差带图_塞规公差2017
  20. Python工程师从菜鸟到大师 之.语法基础之条件语句、循环语句和函数 02

热门文章

  1. ubuntu服务器lxde桌面,UBUNTU最小化搭建LXDE桌面环境
  2. Linpack之HPL测试 (HPL Benchmark)
  3. Linux下安装jdk-7u76-linux-x64.tar.gz
  4. CAD梦想画图中的“延伸命令”
  5. 应用范例:解析 Yahoo 奇摩股市的各档股票资讯-HtmlAgilityPack
  6. dp(相对大小) 和 px(像素)之间的相互转换
  7. Java中JDK、JRE、JVM是什么?有什么区别?有什么关系?
  8. input输入IME问题
  9. 免费馅饼-----线性DP
  10. Activiti UEL表达式是如何与Spring 的容器整合起来的