9.kotlin安卓实践课程-用kotlin写第一个fragment的recyclerView的adapter具体实现
简介
主要会通过安卓实战来讲解kotlin语法和实际应用,本教程设及知识点包括框架模式mvp+mvvm, Databinding(数据绑定框架),Dagger2(依赖注入框架),DeepLink(页面路由框架),Rxjava,RxAndroid(异步操作框架),Retrofit,Okhtttp等,不过本教程重点在kotlin所以这些框架需要了解可自行百度。
针对人群:Android中级以上,kotlin入门
本系列最后一篇我们看看recyclerView的adapter怎么实现的
首先先看一下代码
/** * Created by bigman on 18-05-18. */ class AndroidAdapter(private val mList: List<AndroidBean>) :BaseBindingAdapter<ItemAndroidBinding>() { override fun getItemCount(): Int { return mList.size } override fun onBindViewHolder(holder: DataBoundViewHolder<ItemAndroidBinding>, position: Int) { super.onBindViewHolder(holder, position) //数据绑定 holder.binding.androidbean = mList[position] //数据立即绑定而不是在下一帧的时候才绑定,避免闪烁和数据错乱 holder.binding.executePendingBindings() } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DataBoundViewHolder<ItemAndroidBinding> { return DataBoundViewHolder( ItemAndroidBinding.inflate(LayoutInflater.from(parent.context), parent, false)) } }
首先看主构造函数和继承
class AndroidAdapter(private val mList: List<AndroidBean>) :BaseBindingAdapter<ItemAndroidBinding>()
- 主构造函数传入一个
List<AndroidBean>
类型的mList
只读变量 - 继承至
BaseBindingAdapter<ItemAndroidBinding>()
下一步我们看一下基类BaseBindingAdapter
的具体实现
/** * Created by bigman on 18-05-18. */ abstract class BaseBindingAdapter<B : ViewDataBinding> : RecyclerView.Adapter<DataBoundViewHolder<B>>() { var mListener: ((pos: Int) -> Unit)? = null override fun onBindViewHolder(holder: DataBoundViewHolder<B>, position: Int) { holder.binding.root.setOnClickListener { mListener?.invoke(holder.adapterPosition) } } fun setOnItemClickListener(listener: ((pos: Int) -> Unit)) { mListener = listener } }
- 大家可以看到
BaseBindingAdapter
需要传入ViewDataBinding
类型,这个ViewDataBinding
是databinding里面所有视图bingding类的基类, - 然后毫无疑问它必须继承于
RecyclerView.Adapter<DataBoundViewHolder<B>>
,这个我们平时写java的RecyclerView.Adapter的时候都需要继承的
这里还有一个DataBoundViewHolder<B>
,看一下代码实现
/** * Created by bigman on 18-05-18. */ class DataBoundViewHolder<T : ViewDataBinding>(val binding:T) : RecyclerView.ViewHolder(binding.root) { }
其实它就是一个RecyclerView.ViewHolder
,只是这里我们传入了通用的ViewDataBinding
使它变成可以绑定任意视图
回到BaseBindingAdapter
,这个基类主要功能就是实现一个通用的databinding用的适配器,只要传入databinding视图类型即可,类内部提供了一个点击事件的回调方法
然后再回到AndroidAdapter
这里主要由三个方法,
-
getItemCount ()
返回绑定列表长度, -
onBindViewHolder ()
实现视图数据绑定,这里用的databingding的数据绑定,holder.binding.executePendingBindings()
,这句代码比较重要不加可能导致数据错乱或者页面闪烁 -
onCreateViewHolder()
主要是完成databinding的holder构建
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DataBoundViewHolder<ItemAndroidBinding> { return DataBoundViewHolder( ItemAndroidBinding.inflate(LayoutInflater.from(parent.context), parent, false)) }
这里的 ItemAndroidBinding
是databinding根据我们的布局文件自动生成的,我们看一下我们这个列表条目布局代码,名称item_android.xml注意对比databinding生成的binding类名称
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:app="http://schemas.android.com/apk/res-auto"> <data> <import type="android.view.View" /> <variable name="androidbean" type="com.bigman.kotlin.bean.AndroidBean" /> </data> <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_marginLeft="2dp" android:layout_marginRight="2dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:background="#fff" android:orientation="vertical" app:cardCornerRadius="5dp" android:paddingTop="10dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:orientation="vertical" android:paddingLeft="16dp" android:paddingBottom="10dp" android:paddingRight="16dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{androidbean.desc}" android:textColor="#000" android:textSize="16sp" /> <ImageView android:layout_width="match_parent" android:layout_height="200dp" android:layout_marginTop="10dp" android:scaleType="center" android:visibility="@{androidbean.hasImg()?View.VISIBLE:View.GONE}" app:load_image="@{androidbean.images[0]}" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_marginTop="10dp" android:text="@{androidbean.who}" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" /> <TextView android:layout_marginTop="10dp" android:text = "@{androidbean.create()}" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout> </android.support.v7.widget.CardView> </layout>
具体代码和前面说过的布局没啥太大区别,主要就是data数据的传入和数据绑定
眼神比较犀利的同学可能会看到几个比较不一样的地方而存在疑惑,我们看看是哪里
<ImageView android:layout_width="match_parent" android:layout_height="200dp" android:layout_marginTop="10dp" android:scaleType="center" android:visibility="@{androidbean.hasImg()?View.VISIBLE:View.GONE}" app:load_image="@{androidbean.images[0]}" />
这里的app:load_image
这是''databinding允许的一个函数绑定形式
我们看一下具体实现:
/** * Created by bigman on 18-05-18. */ @BindingAdapter("load_image") fun loadImage(imageView: ImageView, url: String?) = Glide.with(imageView.context).load(url) .crossFade() .into(imageView) @BindingAdapter("set_text") fun setText(textView: TextView, string: String) { textView.setText("bigman" + string) } @BindingAdapter("load_asset") fun loadAsset(imageView: ImageView, id: Int) = Glide.with(imageView.context).load(id).into(imageView)
这几个函数被我卸载随意的一个kt文件里面,然后通过 @BindingAdapter
注解,我们的databinding框架就能很容易的找到它
那么我们这一系列kotlin 安卓实战内容到这里结束了,虽然kotlin知识点讲的不错,但是基本的运用知道这些也差不多够了,大家可以自己动手写一下,本系列主要目的已经达到,就是kotlin在这种mvp+mvvm目前最合理框架上的具体应用
欢迎一起交流,有问题加群交流
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
8.kotlin安卓实践课程-用kotlin写第一个fragment
简介 主要会通过安卓实战来讲解kotlin语法和实际应用,本教程设及知识点包括框架模式mvp+mvvm, Databinding(数据绑定框架),Dagger2(依赖注入框架),DeepLink(页面路由框架),Rxjava,RxAndroid(异步操作框架),Retrofit,Okhtttp等,不过本教程重点在kotlin所以这些框架需要了解可自行百度。 针对人群:Android中级以上,kotlin入门 我们马上开始完成第一个kotlin代码实现的fragment 首先先看一下代码 /** * * Created by bigman on 18-05-18. */ class AndroidFragment : BaseBingingFragment<ViewRecyclerBinding>(), AndroidContract.View { private var mList = ArrayList<AndroidBean>() private lateinit var mAdapter: AndroidAdapter private var mPage ...
- 下一篇
iOS 开发之解决 MMDrawerController 侧滑菜单与中心视图手势冲突
MMDrawerController 是一个很好用的实现抽屉效果的第三方类,但有时候当我们在中心视图的子视图控制器中需要使用手势进行其他操作的时候会产生手势冲突,导致运行效果不符合我们的想象。那么问题来了,该怎么解决冲突问题呢? 下面是我在使用过程中的个人总结: 需求: 1、只有左抽屉和中心视图控制器,在中心视图的子视图控制器右滑可以打开左抽屉。 2、中心视图的子视图控制器中的 Cell 可通过滑动手势显示自定义 Cell 中的删除按钮 问题: 1、由于删除 Cell 的左滑手势和 MMDrawerController 的打开右抽屉的左滑手势有冲突,导致左滑显示自定义 Cell 删除按钮的方法不响应。 期待效果: 1、解除删除 Cell 的手势冲突 2、右滑可以打开左抽屉 思考过程: MMDrawerController 中应该有一个识别手势的方法,只要找到这个方法问题就可以得到解决。 解决过程: 1、在 MMDrawerController 文件夹下的各个.m文件中通过 Command+F 搜寻 GestureRecognizer,最终在 MMDrawerController 这个类...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Red5直播服务器,属于Java语言的直播服务器
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS6,CentOS7官方镜像安装Oracle11G
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS8安装Docker,最新的服务器搭配容器使用