|
|
|
|
公众号矩阵

【懒人专属】通用RecylerAdapter,内置XRecyclerView,兼容上下拉与动画,高复用,通用所有页面,支持空页

RecylerView相信大家都听过(你确定要说没听过 = =),在ListView横行的年代里,RecyclerView携带了褒贬不一的评价,开始进入了我们的视线,那时候刚好开始了新的项目,正好就拿它练手了。下方进入介绍使用流程,建议对着Demo撸起来。

作者:恋猫的小郭来源:安卓巴士Android开发者门户|2017-01-03 11:10

Hello大家好,郭老司机又来了。以前都是看文章的小喵同志,如今终于体也会到码字的不易,作为一个沉默寡言的程序猿,对于码文无数的前辈深表敬佩((/- -)/。

RecylerView相信大家都听过(你确定要说没听过 = =),在ListView横行的年代里,RecyclerView携带了褒贬不一的评价,开始进入了我们的视线,那时候刚好开始了新的项目,正好就拿它练手了。下方进入介绍使用流程,建议对着Demo撸起来。( ・᷄-・᷅ )

正常情况下,对于每一个不同的列表,我们经常需要实现不同的Adapter ,来处理对应的逻辑,这样导致了我们有着许多重复的代码,在优化代码(懒)这种动力的驱动下,个人实现了一个通用的Adapter。后面所说的Holder,可以理解为列表中一个Item,属于它的逻辑处理类,每一种类型的Item有一种Holder。

只需要一个Adapter,你就可以实现各种类型的列表,在一个列表里兼容不同类型的Item,你需要做的,仅仅是维护你的Holder(类似List里的一个Item)和Model,无需再关心其他,实现高复用与多样式逻辑,外带支持自定义动画,多种上下拉实现方式,不需要再写任何Adapter代码(^o^)/。

1、 CommonRecyclerManager :绑定layoutId和你的Holder类名。

这个管理类是用于绑定Holder和R.layout.xxx,这样在后面CommonRecyclerAdapter 用它通过数据Model的layoutId,找到对应的Holder并创建它。

  1. //将布局的ID和holder类型关联commonRecyclerManager.addType(TextHolder.ID, TextHolder.class.getName()); 

2、 RecyclerBaseHolder :继承这个Holder,实现你的需求。

RecyclerBaseHolder的所有Holder的基类,他继承了RecyclerView.ViewHolder,并定义写两个方法,所以你继承它就对了,在createView的时候找到控件,在onBind读取数据填充画面。这里就是实现你梦想的地方!

  1. //实现的hodler继承RecyclerBaseHolder,重载下面方式实现你的需求 
  2. public class TextHolder extends RecyclerBaseHolder { 
  3.     //布局id,一般我习惯吧这个Holder需要处理的id都写在这里,方便管理 
  4.     public final static int ID = R.layout.text_item; 
  5.     @BindView(R.id.item_text) 
  6.     TextView itemText; 
  7.  
  8.     public TextHolder(Context context, View v) { 
  9.         super(context, v); 
  10.     }     
  11.  
  12.     /iew创建好了 
  13.     @Override  
  14.     public void createView(View v) { 
  15.         ButterKnife.bind(this, v); 
  16.     } 
  17.  
  18.     /iew创建好了,更具数据处理逻辑 
  19.     @Override 
  20.     public void onBind(RecyclerBaseModel model, int position) { 
  21.         //转化为你的model 
  22.         TextModel textModel = (TextModel) (model); 
  23.         itemText.setText(textModel.getText()); 
  24.     } 
  25.  
  26.     //不需要可以不写 
  27.     @Override 
  28.     public AnimatorSet getAnimator(View view) { 
  29.         //实现你的动画 
  30.         return null
  31.     } 
  32. }  

3、 CommonRecyclerAdapter :通用的适配器

只需要传入数据List和CommonRecyclerManager,就会根据Model的顺序,通过数据的layoutId,在RecyclerView中自动生成对应的Holder,其他的功能只需要简单的配置即可。

  1. //用数据和manager创建 
  2.  
  3. adapteradapter = new CommonRecyclerAdapter(getActivity(), commonRecyclerManager, datas); 
  4.  
  5.  
  6. //支持需要加载更多 
  7.  
  8. adapter.setNeedLoadMore(true); 
  9.  
  10.  
  11. //支持空数据显示 空页面 
  12.  
  13. adapter.setShowNoData(true); 
  14.  
  15.  
  16. //设置item显示动画支持打开 
  17.  
  18. adapter.setNeedAnimation(true); 

4、RecyclerBaseModel :数据model的积累,必须继承它,不离不弃。

继承它的作用是,因为整个Adapter都是以它为基类,你需要继承他,最终的是,你需要这个Model对应的布局Id,这样它才能找到属于自己的Holder。

  1. //继承RecyclerBaseModel实现你需要的数据类型public class TextModel extends RecyclerBaseModel { 
  2.    private String text = ""
  3.  
  4.    public String getText() {        return text; 
  5.    } 
  6.  
  7.    public void setText(String text) {        this.text = text; 
  8.    } 

总结起来就是

1、实现你的Holder并继承RecyclerBaseHolder,这里是你实现需求的地方,相当于Item的逻辑。

2、让你的数据model继承RecyclerBaseModel,设置Model的LayoutId(很重要),这样model就会通过CommonRecyclerManager,找到LayoutId对应关联的Holder,并生成它。

3、你需要一个CommonRecyclerManager来绑定你的LayoutId和处理这布局的Holder类名。

4、通过CommonRecyclerManager和Model的数据列表生成CommonRecyclerAdapter。

5、把Adapter交给Recycler。

逻辑看起来是不是有些复杂?其实就是model的LayoutId,CommonRecyclerManager通过关联了处理它的Holder。这样我们只需要在数据List里,根据数据设置不同的LayoutId的model,Adapter就会自动匹配对应的Holder。

如此一来,<( ̄︶ ̄)>你只需要实现好Holder和组装好Model,任何列表都可以使用起来,不需要再写Adapter逻辑了。根据model的顺序,Adapter自动生成对应的Holder,并且同一个Holder是可以绑定不同的LayoutId,以后你只需要维护和兼容你的Holder,在各个列表里通用的你holder逻辑了,是不是瞬间代码干净了好多?

下拉刷新与上拉加载更多

普通的列表,直接使用系统的SwipeRefreshLayout就可以啦,简单有好用。下拉加载更多直接添加下方方法,轻松实现上下拉刷新<( ̄︶ ̄),简单粗暴,就是记得要加个锁避免重复进入。

  1. //打开支持需要加载更多adapter.setNeedLoadMore(true); 
  2.  
  3. recycler.addOnScrollListener(new LoadMoreScrollListener() {    @Override 
  4.    public void onLoadMore() {        //注意加锁 
  5.        if (!isLoadMore) { 
  6.            isLoadMore = true
  7.            recycler.postDelayed(new Runnable() {                @Override 
  8.                public void run() { 
  9.                    isLoadMore = false
  10.                    loadMore(); 
  11.                } 
  12.  
  13.            }, 2000); 
  14.        } 
  15.    }    //当前***个可视的是哪个item 
  16.    @Override 
  17.    public void onScrolled(int firstPosition) { 
  18.    } 
  19. }); 

其他配置

你还可以配置是否显示动画效果,配置上拉loading的颜色,单击和长按等,看下面。

  1. //支持空数据显示 空页面 
  2.  
  3. adapter.setShowNoData(true); 
  4.  
  5.  
  6. //显示空数据model,不设置显示默认空页面 
  7.  
  8. adapter.setNoDataModel(noDataModel); 
  9.  
  10.  
  11. //显示空数据页面布局,不设置显示默认,布局id需要通过CommonRecyclerManager关联hodler 
  12.  
  13. adapter.setNoDataLayoutId(noDataLayoutId); 
  14.  
  15.  
  16. //设置动画支持打开 
  17.  
  18. adapter.setNeedAnimation(true); 
  19.  
  20.  
  21. //添加点击 
  22.  
  23. adapter.setOnItemClickListener(); 
  24.  
  25. XRecyclerView兼容支持 

这里添加了XRecyclerView,并且对其进行了修改。XRecyclerView内置了内部Adapter,使其支持添加头部,自带上下拉效果的控件,部分调整之后,全面支持CommonRecyclerAdapter。

不需要监听滑动,不需要SwipeRefreshLayout,轻松添加刷新与加载更多。而且更是支持动态配置,上下拉的各种样式支持,具体在ProgressStyle下有多种类型支持配置,解决了Adapter对瀑布流上拉的支持不够兼容的问题。

这里使用方式,和普通的RecyclerView一样,支持和CommonRecyclerAdapter的配合,而且它同样支持空页面显示,还支持添加各种头部,唯一需要注意的是,添加分割线类addItemDecoration和点击的时候,需要针对添加了头部,和刷新的绝对的position,换算成相对的位置,此处曾经把自己坑哭了╥﹏╥...,下面看代码吧。

  1. //是否屏蔽下拉 
  2.  
  3. //xRecycler.setPullRefreshEnabled(false); 
  4.  
  5. //上拉加载更多样式,也可以设置下拉 
  6.  
  7. xRecycler.setLoadingMoreProgressStyle(ProgressStyle.SysProgress); 
  8.  
  9. //设置管理器,关联布局与holder类名,不同id可以管理一个holder 
  10.  
  11. CommonRecyclerManager commonRecyclerManager = new CommonRecyclerManager(); 
  12.  
  13. commonRecyclerManager.addType(ImageHolder.ID, ImageHolder.class.getName()); 
  14.  
  15. commonRecyclerManager.addType(TextHolder.ID, TextHolder.class.getName()); 
  16.  
  17. commonRecyclerManager.addType(ClickHolder.ID, ClickHolder.class.getName()); 
  18.  
  19. //初始化通用管理器 
  20.  
  21. commonRecyclerAdapter = new CommonRecyclerAdapter(getActivity(), commonRecyclerManager, dataList); 
  22.  
  23. xRecycler.setAdapter(commonRecyclerAdapter); 
  24.  
  25.  
  26. ImageView imageView = new ImageView(getActivity()); 
  27.  
  28. imageView.setImageResource(R.drawable.xxx1); 
  29.  
  30. imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 
  31.  
  32. imageView.setMinimumHeight(dip2px(getActivity(), 100)); 
  33.  
  34. //添加头部 
  35.  
  36. xRecycler.addHeaderView(imageView); 
  37.  
  38. //本身也支持设置空局部 
  39.  
  40. //xRecycler.setEmptyView(); 
  41.  
  42. xRecycler.setLoadingListener(new XRecyclerView.LoadingListener() { 
  43.  
  44.     @Override 
  45.  
  46.     public void onRefresh() { 
  47.  
  48.         xRecycler.postDelayed(new Runnable() { 
  49.  
  50.             @Override 
  51.  
  52.             public void run() { 
  53.  
  54.                 xRecycler.refreshComplete(); 
  55.  
  56.             } 
  57.  
  58.         }, 2000); 
  59.  
  60.     } 
  61.  
  62.  
  63.     @Override 
  64.  
  65.     public void onLoadMore() { 
  66.  
  67.         xRecycler.postDelayed(new Runnable() { 
  68.  
  69.             @Override 
  70.  
  71.             public void run() { 
  72.  
  73.                 loadMore(); 
  74.  
  75.             } 
  76.  
  77.         }, 2000); 
  78.  
  79.     } 
  80.  
  81. }); 
  82.  
  83.  
  84. commonRecyclerAdapter.setOnItemClickListener(new OnItemClickListener() { 
  85.  
  86.     @Override 
  87.  
  88.     public void onItemClick(Context context, int position) { 
  89.  
  90.         //需要减去你的header和刷新的view的数量 
  91.  
  92.         Toast.makeText(getActivity(), "点击了!! " + (position - 2), Toast.LENGTH_SHORT).show(); 
  93.  
  94.     } 
  95.  
  96. }); 

***

到这里你已经知道了大致的用法了吧。详细的内部实现,可以通过DEMO查看。大致逻辑是 CommonRecyclerManager 关联接layoutId和Holder类名,CommonRecyclerAdapter通过Model的layoutId找到这个Holder,然后用layoutId创建view,把View、position、model传入到Holder里面实现数据填充。所layoutId也是*类型id**,注意:

使用的时候切记要给你的model设置setResLayoutId(),这是最容易让人遗忘的。

【编辑推荐】

  1. Android: 自定义View
  2. 怎样在Android上手动备份你的短信/彩信?
  3. Android适配难题全面总结
  4. Gradle for Android系列:为什么Gradle这么火
  5. Android开发的那些坑和小技巧
【责任编辑:枯木 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

16招轻松掌握PPT技巧

16招轻松掌握PPT技巧

GET职场加薪技能
共16章 | 晒书包

289人订阅学习

20个局域网建设改造案例

20个局域网建设改造案例

网络搭建技巧
共20章 | 捷哥CCIE

645人订阅学习

WOT2019全球人工智能技术峰会

WOT2019全球人工智能技术峰会

通用技术、应用领域、企业赋能三大章节,13大技术专场,60+国内外一线人工智能精英大咖站台,分享人工智能的平台工具、算法模型、语音视觉等技术主题,助力人工智能落地。
共50章 | WOT峰会

0人订阅学习

读 书 +更多

Reversing:逆向工程揭密

本书描述的是在逆向与反逆向之间展开的一场旷日持久的拉锯战。作者Eldad Eilam以一个解说人的身份为我们详尽地评述了双方使用的每一招每一...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO播客