ListAdapter封装 (上) - SimpleAdapter

前言:

上一篇文章已经讲解 ListAdapter 的基本使用;  这次 我们不再关心 实体类型、Item事件回调,  编写统一 DiffCallback,  布局ID传入.

使用:

1. 首先新建 BaseItem: 列表实体都会实现此接口.  它是 BaseAdapter 的默认实体类型

interface BaseItem {
/**
* 条目更新标记, 用于 DiffUtil areContentsTheSame
*/
var hasChanged: Boolean /**
* Adapter 中的 ItemType.
* 单类型布局可以不用关心 该返回值
* 多类型布局中; 需直接返回布局Id; 例如: R.layout.item_test
*/
fun getMItemType(): Int = 0
}

2. 再创建实体类,  实现 BaseItem 接口;  除了  hasChanged,  只有一个 title 参数;

class TestEntity(
var title: String? = null,
override var hasChanged: Boolean = false
) : BaseItem

3.编写通用的 DiffCallback;  实体类型就用 BaseItem 

areItemsTheSame(): 我们选用比较内存地址的方式;

areContentsTheSame(): 我们选择状态标记方式;

class DiffCallback: DiffUtil.ItemCallback<BaseItem>() {
/**
* 比较两个条目对象 是否为同一个Item
*/
override fun areItemsTheSame(oldItem: BaseItem, newItem: BaseItem): Boolean {
return oldItem === newItem
} /**
* 再确定为同一条目的情况下; 再去比较 item 的内容是否发生变化;
* 我们使用 状态标识方式判断;
* @return true: 代表无变化; false: 有变化;
*/
override fun areContentsTheSame(oldItem: BaseItem, newItem: BaseItem): Boolean {
return !oldItem.hasChanged
}
}

4.接下来是 ViewHolder:  用于 item 绑定数据,及缓存控件.   我们加入事件处理 handler; 以及重置状态标记;

open class NewViewHolder(val binding: ViewDataBinding, private val handler: BaseHandler?) : RecyclerView.ViewHolder(binding.root){
open fun bind(item: BaseItem?) {
//重置 状态标记
item?.hasChanged = false
binding.setVariable(BR.item, item)
binding.setVariable(BR.handler, handler)
binding.executePendingBindings()
}
}

5. Handler : MVVM 模式中 Item事件响应处理类;

基类: BaseHandler   它几乎只出现在 Adapter相关基类中,省的我们再写泛型;   要使用还得用它的子类

子类: Handler  提供具体实体泛型.  供布局文件使用

/**
* item 事件响应基类, 这类什么都不用写
*/
open class BaseHandler /**
* item 事件响应基类, 需提供具体的实体类泛型;
*/
abstract class Handler<T: BaseItem> : BaseHandler() {
abstract fun onClick(view: View, info: T)
}

6.下面是重头戏了:  BaseAdapter

重头戏?但它却如此简单  [捂脸] (自带转义);   只需要传入 BaseHandler 对象;  并重写 onBindViewHolder 即可;

我还重写了 submitList();  因为ListAdapter 提交数据时,会判断前后数据集合是否为同一内存地址;  我们让它必定以新数据集对象传入; (虽然个人感觉这样不对, 但博主还就踩上这坑了 [机智])

abstract class BaseAdapter(
protected val handler: BaseHandler? = null) :
ListAdapter<BaseItem, NewViewHolder>(DiffCallback()) { override fun onBindViewHolder(holder: NewViewHolder, position: Int) {
holder.bind(getItem(position))
} /**
* 重写 提交数据方法, 让它必定以新数据集合对象传入
*/
override fun submitList(list: MutableList<out BaseItem>?) {
val newData = mutableListOf<BaseItem>()
if (list != null) {
newData.addAll(list)
}
super.submitList(newData)
}
}

7. 重头戏中的重头来了 SimpleAdapter: 

好吧, 它更简单.  继承 BaseAdapter 并传入 layoutId, 再重写 onCreateViewHolder 即可;

open class SimpleAdapter(
/**
* 布局id;
*/
private val layout: Int,
handler: BaseHandler? = null
) :
BaseAdapter(handler) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NewViewHolder {
return NewViewHolder(
DataBindingUtil.inflate(
LayoutInflater.from(parent.context), layout, parent, false
), handler
)
}
}

8. 好了封装完事.  接下来我们要开始用了!  使用也非常简单

//只需要传入  布局id 及 事件响应 Handler
mAdapter = SimpleAdapter(R.layout.item_test_mvvm, object : Handler<TestEntity>(){
override fun onClick(view: View, info: TestEntity) {
Toast.makeText(mActivity, "点了条目", Toast.LENGTH_SHORT).show()
}
})
mDataBind.rvRecycle.let {
it.layoutManager = LinearLayoutManager(mActivity)
it.adapter = mAdapter
}
val data = mutableListOf(TestEntity("第一条"), TestEntity("第一条"), TestEntity("第一条"), TestEntity("第一条"), TestEntity("第一条"))
mAdapter.submitList(data)

9. 好吧,再贴出我的 布局文件:

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
<variable
name="item"
type="com.example.kotlinmvpframe.network.entity.TestEntity" />
<variable
name="handler"
type="com.example.kotlinmvpframe.test.testtwo.Handler" />
</data> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:onClick="@{(view) -> handler.onClick(view, item)}"
android:padding="20dp">
<TextView
android:id="@+id/btn2"
style="@style/tv_base_16_dark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{item.title}" />
</LinearLayout>
</layout>

好的! over

下一篇再讲  多条目类型, 嵌套RecycleView, 封装头尾 等等! 敬请期待

回到顶部

孟老板 ListAdapter封装, 告别Adapter代码 (上)的更多相关文章

  1. 孟老板 ListAdapter封装, 告别Adapter代码 (三)

    BaseAdapter系列 ListAdapter封装, 告别Adapter代码 (一) ListAdapter封装, 告别Adapter代码 (二) ListAdapter封装, 告别Adapter ...

  2. 孟老板 ListAdapter封装, 告别Adapter代码 (四)

    BaseAdapter系列 ListAdapter封装, 告别Adapter代码 (一) ListAdapter封装, 告别Adapter代码 (二) ListAdapter封装, 告别Adapter ...

  3. 孟老板 BaseAdapter封装(五) ListAdapter

    BaseAdapter封装(一) 简单封装 BaseAdapter封装(二) Header,footer BaseAdapter封装(三) 空数据占位图 BaseAdapter封装(四) PageHe ...

  4. 孟老板 BaseAdapter封装 (三) 空数据占位图

    BaseAdapter封装(一) 简单封装 BaseAdapter封装(二) Header,footer BaseAdapter封装(三) 空数据占位图 BaseAdapter封装(四) PageHe ...

  5. 孟老板 BaseAdapter封装(四) PageHelper

    BaseAdapter封装(一) 简单封装 BaseAdapter封装(二) Header,footer BaseAdapter封装(三) 空数据占位图 BaseAdapter封装(四) PageHe ...

  6. 孟老板 BaseAdapter封装 (一) 简单封装

    BaseAdapter封装(一) 简单封装 BaseAdapter封装(二) Header,footer BaseAdapter封装(三) 空数据占位图 BaseAdapter封装(四) PageHe ...

  7. 孟老板 BaseAdapter封装 (二) Healer,footer

    BaseAdapter封装(一) 简单封装 BaseAdapter封装(二) Header,footer BaseAdapter封装(三) 空数据占位图 BaseAdapter封装(四) PageHe ...

  8. 对百度WebUploader的二次封装,精简前端代码之图片预览上传(两句代码搞定上传)

    前言 本篇文章上一篇: 对百度WebUploader开源上传控件的二次封装,精简前端代码(两句代码搞定上传) 此篇是在上面的基础上扩展出来专门上传图片的控件封装. 首先我们看看效果: 正文 使用方式同 ...

  9. 孟老板 Paging3 (二) 结合Room

    BaseAdapter系列 ListAdapter系列 Paging3 (一) 入门 Paging3 (二) 结合 Room Paging3 (二)  结合Room Paging 数据源不开放, 无法 ...

随机推荐

  1. android so加载

    本文分析so加载的步骤,其实在之前dalvik浅析二中也有提及,但那重点关注的是jni.android中so库的加载,代码如下: loadLibrary("nanosleep"); ...

  2. hdu4971 流-最大权闭包

    题意:       给了一些任务,然后给了一些完成某些任务的限制,然后又给了限制之间的拓扑关系,最后问你最大收益. 思路:       很直白,就是流的一个应用,最大权闭包,没涉及到什么想法的地方,建 ...

  3. scrapy爬虫案例--爬取阳关热线问政平台

    阳光热线问政平台:http://wz.sun0769.com/political/index/politicsNewest?id=1&page=1 爬取最新问政帖子的编号.投诉标题.投诉内容以 ...

  4. Spring MVC工作原理及源码解析(一) MVC原理介绍、与IOC容器整合原理

    MVC原理介绍 Spring MVC原理图 上图是Spring MVC工作原理图(图片来自网上搜索),根据上图,我们可以得知Spring MVC的工作流程如下: 1.用户(客户端,即浏览器)发送请求至 ...

  5. Electron-Vue3-Vadmin后台系统|vite2+electron桌面端权限管理系统

    基于vite2.x+electron12桌面端后台管理系统Vite2ElectronVAdmin. 继上一次分享vite2整合electron搭建后台框架,这次带来的是最新开发的跨桌面中后台权限管理系 ...

  6. KMP算法以及优化(代码分析以及求解next数组和nextval数组)

    KMP算法以及优化(代码分析以及求解next数组和nextval数组) 来了,数据结构及算法的内容来了,这才是我们的专攻,前面写的都是开胃小菜,本篇文章,侧重考研408方向,所以保证了你只要看懂了,题 ...

  7. Java集合详解(五):Hashtable原理解析

    概述 本文是基于jdk8_271版本进行分析的. Hashtable与HashMap一样,是一个存储key-value的双列集合.底层是基于数组+链表实现的,没有红黑树结构.Hashtable默认初始 ...

  8. [Java] Spring 示例

    (一)IoC/DI 功能 配置解析:将配置文件解析为BeanDefinition结构,便于BeansFactory创建对象 对象创建:BeansFactory 根据配置文件通过反射创建对象,所有类对象 ...

  9. ubuntu查看已安装软件包信息的方法

    ubuntu查看已安装软件包信息的方法原创fang141x 最后发布于2019-04-15 10:41:34 阅读数 2802 收藏展开简介ubuntu下面是使用dpkg来管理和安装软件包的,对应ce ...

  10. 008.kubernets的调度系统之标签选择器

    一 Kubernetes 调度简介 除了让 kubernetes 集群调度器自动为 pod 资源选择某个节点(默认调度考虑的是资源足够,并且 load 尽量平均),有些情况我们希望能更多地控制 pod ...