关于Graywater的系列文章

  1. RecyclerView的超强辅助Graywater——理论篇
  2. RecyclerView的超强辅助Graywater——基础实操篇
  3. RecyclerView的超强辅助Graywater——点击事件
  4. RecyclerView的超强辅助Graywater——综合实操篇

原本上一篇写完之后就想接着就把实操篇文章给完成了的,但是没想到新需求一来,就加了2周的班,到今天才空下来,才有时间继续完成这篇文章。

上一篇讲解了Graywater的一些基础理论知识,这一篇文章将讲解Graywater的基本使用方法,并搭配了一个基础Demo。下一篇则会讲解Graywater的进阶用法。

注意

以下所使用的Graywater类库,非Graywater最新类库,比最新的旧一点,但是使用起来没有任何问题,个人认为这版比最新的要好理解很多。Graywater官方的类库已经更新到最新,我使用的这个版本Github地址:GraywaterPrimaryDemo Github地址,大家在项目里面可以找到graywater类库。

使用Graywater的步骤

还是要先祭出这张原理图,里面依然是熟悉的5个类,但是多了一些与步骤相关的文字。在GraywaterAdapter实例化之前,我们需要做一些准备工作,也就是将以下步骤中相关类全部创建完成。这是我在实际使用后,觉得最佳的一个文件创建顺序。

基础Demo预览效果

根据上面所说的步骤,我们首先来看看如何使用Graywater做出一个最简单的列表。

先展示一下GraywaterPrimaryDemo项目的目录结构

接下来开始使用Graywater实现上面GIF图的效果,要想使用Graywater,肯定要先导入类库啦。

准备工作:导入Graywater类库

从GraywaterPrimaryDemo中将graywater文件夹拷贝到根目录下,在settings.gradle文件中添加graywater

include ':app', 'graywater'

然后选择菜单栏 File --> Project Structure,选择app—>选择Denpendencies—>选择Module dependency,选择graywater进行依赖。如下图。

成功导入graywater后,我们就可以开始愉快的写代码了。

第一步:新建布局文件adapter_item.xml

布局文件很简单,只有一个ImageView和TextView,一个用来显示图片,一个用来显示文本,就不贴出代码了,大家可以在最后Github GraywaterPrimaryDemo地址里下载完整代码查看。

第二步:创建需要的model类

首先将官方Demo中的Primitive拷贝到model目录下,为什么一定要拷贝这个接口,原因后面再讲解。

因为Demo里面的数据类型只有一种,每个Item就是一串文本,和一个图片url(这里大家最好是用对象来管理)。所以只需要创建一个EntertainPrimitive类来管理所有数据就可以了。同时记得EntertainPrimitive类需要实现Primitive接口。model目录下所有的类都需要实现Primitive接口。

第三步:创建对应的ViewHolder文件

从GraywaterPrimaryDemo的GIF图上可以看到,每一个Item就只有一个ImageView和一个TextView。所以我们需要创建一个ViewHolder来管理这2个控件。首先也是将官方Demo中的PrimitiveViewHolder拷贝到viewholder目录下,然后新建EntertainViewHolder来继承PrimitiveViewHolder,为什么也要拷贝这个的原因也在后面再讲,我们先关注核心步骤。

在EntertainViewHolder中创建一个ImageView和Textview,使用itemView来查找,这跟在RecyclerView.Adapter使用时是一样的。

    private ImageView img;private TextView title;public EntertainViewHolder(View itemView) {super(itemView);img = itemView.findViewById(R.id.img);title = itemView.findViewById(R.id.name);}public ImageView getImg() {return img;}public TextView getTitle() {return title;}

第四步:创建对应的ViewHolderCreator文件

EntertainViewHolder创建好了,接下来就需要新建一个viewholdercreator类来生成viewholder。在viewholdercreator目录下创建EntertainViewHolderCreator类,实现GraywaterAdapter.ViewHolderCreator接口,同时要实现接口中的create方法和getViewType方法。

public class EntertainViewHolderCreator implements GraywaterAdapter.ViewHolderCreator {@Overridepublic RecyclerView.ViewHolder create(ViewGroup parent) {return new EntertainViewHolder(GraywaterAdapter.inflate(parent, R.layout.adapter_item));}@Overridepublic int getViewType() {return R.layout.adapter_item;}
}

create方法返回创建的viewholder对象。
getViewType方法返回的就是item的layoutId。

EntertainViewHolderCreator就是EntertainViewHolder的制造器,专门负责创建EntertainViewHolder对象。有一个需要注意的地方,在new一个EntertainViewHolder对象时,参数是需要传入itemView的,这里使用的GraywaterAdapter.inflate(),查看源码可知,其实就是对LayoutInflater.from(parent.getContext()).inflate();再封装了一层。

GraywaterAdapter.inflate(parent, R.layout.adapter_item)  //实际上就是调用的LayoutInflater.from(parent.getContext()).inflate();

第五步:创建对应的Binder文件

数据model和视图viewholder都创建好了,接下来就可以使用Binder来绑定数据了。创建EntertainBinder类实现GraywaterAdapter.Binder接口,接口里需要传入model的泛型和viewholder的泛型,因为这里是EntertainPrimitive数据所对应的部分,所以直接传EntertainPrimitive和EntertainViewHolder就好。

实现接口里的方法,主要需要重写下面3个方法:

getViewHolderType() : 返回ViewHolder的类型。
bind() : 将model的数据绑定到view上,这里就类似于RecyclerView.Adapter的onBindViewHolder方法。
unbind() :做一些清理操作,一般在里面解除监听事件。

GraywaterPrimaryDemo里的EntertainBinder类也写的很简单

public class EntertainBinder implements GraywaterAdapter.Binder<EntertainPrimitive, EntertainViewHolder> {@NonNull@Overridepublic Class<EntertainViewHolder> getViewHolderType() {return EntertainViewHolder.class;}@Overridepublic void prepare(@NonNull EntertainPrimitive model, List<GraywaterAdapter.Binder<? super EntertainPrimitive, ? extends EntertainViewHolder>> binders, int binderIndex) {}@Overridepublic void bind(@NonNull EntertainPrimitive model, @NonNull EntertainViewHolder holder, @NonNull List<GraywaterAdapter.Binder<? super EntertainPrimitive, ? extends EntertainViewHolder>>binders, int binderIndex, @NonNull GraywaterAdapter.ActionListener<EntertainPrimitive, EntertainViewHolder> actionListener) {Picasso.get().load(model.getUrls().get(binderIndex)).placeholder(R.mipmap.ic_launcher).into(holder.getImg());holder.getTitle().setText(model.getTitles().get(binderIndex));}@Overridepublic void unbind(@NonNull EntertainViewHolder holder) {}}

第六步:创建对应的ItemBinder文件

基本数据model类,视图类viewholder,视图创建器类viewholdercreator类,数据视图绑定类binder类创建好后,就可以创建最后一个ItemBinder类了,这里我们创建对应的EntertainItemBinder类来对EntertainBinder类进行管理。

EntertainItemBinder类的一个作用就是使用getBinderList()方法返回当前所管理所有Binder对象。

    public List<GraywaterAdapter.Binder<? super EntertainPrimitive, ? extends PrimitiveViewHolder>> getBinderList(@NonNull final EntertainPrimitive model, int position) {return new ArrayList<GraywaterAdapter.Binder<? super EntertainPrimitive, ? extends PrimitiveViewHolder>>() {{for (String s : model.getTitles()) {add(entertainBinder);}}};}

说一下为什么要写for循环,Demo中可以看到,每一个福原爱Item就是一个子数据,对应着一个ViewHolder和一个Binder,所以一个EntertainPrimitive的model里有多少个titles就对应了有多少个子数据,就添加到binderlist中,再一起返回,数据就能显示出来了。

最后一步,创建PrimitiveAdapter

所有准备工作做好了,就可以创建适配器PrimitiveAdapter来继承GraywaterAdapter了,注意这里因为要传入3个泛型参数,分别是model、viewholder和model的class类型

public class PrimitiveAdapter extends GraywaterAdapter<Primitive, PrimitiveViewHolder, Class<? extends Primitive>> {public PrimitiveAdapter() {register(new EntertainViewHolderCreator(), EntertainViewHolder.class);  //将creator和对应的viewholder绑定EntertainBinder entertainBinder = new EntertainBinder();EntertainItemBinder entertainItemBinder = new EntertainItemBinder(entertainBinder);register(EntertainPrimitive.class, entertainItemBinder, null);  //将itemBinder和指定的数据类型绑定}@Overrideprotected Class<? extends Primitive> getModelType(Primitive model) {return model.getClass();}
}

可以看到有2个register()方法,一个是绑定viewholder和viewholdercreator的,一个是绑定itemBinder和数据类型的。实际上register()方法就是把对应的数据放入到map集合中,然后迅速查找对应的对象。每个数据类型的register只需要写一次就够了。可以看到第二个register()方法的第三个参数传入了null值,这是因为第三个参数是拿来传入点击事件的listener的。没有点击事件就可以直接传入null,需要点击事件就让ItemBinder类实现GraywaterAdapter.ActionListener接口,再传入register方法中。

疑问解答

前面的部分留下了2个疑问,为什么一定要将Primitive和PrimitiveViewHolder类拷贝到对应目录下,并需要继承。我们可以从上面ItemBinder传入的泛型看到是Primitive和PrimitiveViewHolder。这就是泛型的魅力了,在不同的数据类型的情况下,比如还有SportsPrimitive、NewsPrimitive或SportsViewHolder和NewsViewHolder类,因为都实现了Primitive接口,继承了PrimitiveViewHolder类的原因,就能在PrimitiveAdapter中统一管理。

Primitive接口还有一个作用,就是用来区别不同的数据类型。这个可以在Graywater的官方Demo中看到,接下来的一篇Graywater的进阶使用也会讲到。

显示RecyclerView

到这里,Graywater的部分就创建完了。我们只需要在MainActivity中,将EntertainPrimitive赋值,再传给PrimitiveAdapter就可以使用了。

    private void initData() {List<String> urls = new ArrayList<>();List<String> titles = new ArrayList<>();for (int i = 0; i < 40; i++) {urls.add("http://n.sinaimg.cn/ent/4_img/upload/0b3147ad/107/w1024h683/20181023/M34_-hmuuiyw5724330.jpg");titles.add("item " + (i + 1) + " : " + "福原爱现身退役发布会挥泪告别 甜美比心畅聊感慨");}mEntertainPrimitive = new EntertainPrimitive(urls, titles);}private void initContentView() {mRecyclerView = findViewById(R.id.recyclerview);mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));mPrimitiveAdapter = new PrimitiveAdapter();mRecyclerView.setAdapter(mPrimitiveAdapter);}private void updateRecyclerView() {mPrimitiveAdapter.add(mEntertainPrimitive);mPrimitiveAdapter.notifyDataSetChanged();}

总结

按照步骤一步步下来,创建Graywater的过程还是很清晰的。大家有什么疑问可以在评论区提问。

GraywaterPrimaryDemo Github地址
如果对大家有帮助的话,希望大家点下star,谢谢,

如果对你有帮助的话,点赞、评论、赞赏都是对我的鼓励,也是支持我写下去的动力,谢谢!

RecyclerView的超强辅助Graywater——基础实操篇相关推荐

  1. RecyclerView的超强辅助Graywater——综合实操篇

    关于Graywater的系列文章 RecyclerView的超强辅助Graywater--理论篇 RecyclerView的超强辅助Graywater--基础实操篇 RecyclerView的超强辅助 ...

  2. RecyclerView的超强辅助Graywater——理论篇

    关于Graywater的系列文章 RecyclerView的超强辅助Graywater--理论篇 RecyclerView的超强辅助Graywater--基础实操篇 RecyclerView的超强辅助 ...

  3. RecyclerView的超强辅助Graywater——点击事件

    关于Graywater的系列文章 RecyclerView的超强辅助Graywater--理论篇 RecyclerView的超强辅助Graywater--基础实操篇 RecyclerView的超强辅助 ...

  4. Linux入门笔记-尚硅谷韩顺平-基础篇实操篇

    文章目录 课程导论 基础篇 Linux入门 Linux介绍 Linux和Unix的关系 Linux和Windows比较 基础篇 Linux的目录结构 基本介绍 具体的目录结构 实操篇 vi和vim的使 ...

  5. 计算机居中试题,计算机基础实操试题.doc

    计算机基础实操试题 全市统考计算机(非专业)实操试题 操作说明: 考试时间为50分钟: 2.本试题均在WINXP.office2003环境下完成: 第一题Windows操作系统的基本操作:(10分) ...

  6. Linux实操篇笔记

    Linux实操篇 远程登陆Linux 先检查一下sshd服务打开没有( " * " 表示打开): setup 选择系统设置,进入下面页面: Xshell 是一个强大的安全终端模拟软 ...

  7. 第五章-Linux实操篇

    title: 第五章 Linux实操篇 categories: Linux tags: linux typora-root-url: - abbrlink: 93414991 date: 2019-0 ...

  8. CRM项目开发【实操篇----市场活动模块】

    CRM项目开发[实操篇----市场活动模块] 前言:本项目来源于B站动力节点视频,CRM项目开发 使用的后端技术栈主要是SSM框架,不涉及boot,老师讲的非常细致,推荐 关于流程图部分,由于是老师创 ...

  9. Linux实操篇,开机重启和用户注销

    Linux实操篇,开机重启和用户注销 1. shutdown shutdown -h now :立即关机 shutdown -h 1 :一分钟后关机 shutdown -r now :立即重启 hal ...

最新文章

  1. Android 让EditText不可编辑
  2. 读《惰者集》有感:数学是一门需要敏锐感觉的学问
  3. java8循环怎么给全局变量累加_JAVA使用for循环会重复调用list.size()吗?
  4. 【锋利的Jquery】读书笔记五
  5. Gestalt - 在浏览器里用 python/ruby 写客户端脚本
  6. TDD:MS自带的单元测试 之 线程模型和执行顺序
  7. java mysql order by,java-使用LIMIT和MySQL进行ORDER BY
  8. Hadoop平台 以Parcel包安装CDH
  9. ijkplayer 视频播放
  10. javascript里的几种常见的数组方法
  11. Django 配置访问静态文件
  12. 012 Ceph多区域网关
  13. 实验一 结构化分析(软件工程)
  14. TrustedInstaller权限的问题
  15. 励志:滴滴打车App初期是怎么推广的?
  16. python接入讯代理_[Python3网络爬虫开发实战] 9.3-付费讯代理、阿布云代理的使用...
  17. 【题解】CF760B:Frodo and pillows
  18. 自然码官方辅助码键位图
  19. Knol of Fabio Maulo
  20. 批量下载NCBI各种数据的方法集合

热门文章

  1. 双击图标出现属性,要右键打开的原因及解决
  2. 计算机视觉的创新,谈计算机视觉课程的教学创新
  3. “假明星”账号背后的黑产链条
  4. 【课上笔记】第二章 线性表
  5. ElasticSearch中含有Object类型和数组对象的查询
  6. internal/modules/cjs/loader.js:x throw err; ^ Error: Cannot find module ‘C:\Program Files
  7. IE10及其以下版本不支持Javascript Map对象(“Map”未定义)
  8. pythonpandas筛选_Python+pandas执行Excel筛选编辑功能
  9. .docx,.doc,.pptx,.ppt,.xlsx,.pdf后缀文档图标不显示
  10. sony z1 android 6.0,索尼最强旗舰Xperia Z1升级版初体验