博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用Kotlin实现极简回调
阅读量:6965 次
发布时间:2019-06-27

本文共 2874 字,大约阅读时间需要 9 分钟。

前言

在各种开发场景中,回调都有着广泛的应用,命名往往是各种CallbackListener,其中在Android中接触最早也最常用的可能就是View.OnClickListener了。

mBtn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Log.d("MM","Click");            }        });复制代码

不过写多了也有点烦恼,我只想打印一条日志,却写了这么多代码。不过好在这个接口里面只包含一个方法,但换做一些包含方法数量比较多的回调就显得比较臃肿了:

mEdit.addTextChangedListener(new TextWatcher() {            @Override            public void beforeTextChanged(CharSequence s, int start, int count, int after) {                            }            @Override            public void onTextChanged(CharSequence s, int start, int before, int count) {            }            @Override            public void afterTextChanged(Editable s) {            }        });复制代码

如果你想优化你的代码,让它们看起来更简洁优雅,可以试试Kotlin的中的一些方法。

简化

先来看下Kotlin中的回调:

mBtn.setOnClickListener(object :View.OnClickListener{            override fun onClick(v: View?) {                println("Click")            }        })复制代码

好像一点也没简化嘛,不过因为在 Kotlin 里函数也是参数的一种,在 Java 中只包含一个方法的接口,在 Kotlin 中都可以使用 Lambda 表达式来达成一样的效果。

mBtnCallback.setOnClickListener { println("Click") }复制代码

是不是简单很多了,但上面的用法仅适用于接口中只有一个方法的情况,如果存在多个方法的话,当然也可以简化了:

mEdit.addTextChangedListener {            beforeTextChanged { text, start, count, after -> println("beforeTextChanged") }            onTextChanged { text, start, before, count -> println("onTextChanged") }            afterTextChanged { text -> println("afterTextChanged") }        }复制代码

也可以按需调用其中任意个方法:

mEdit.addTextChangedListener {            onTextChanged { text, start, before, count -> println("onTextChanged") }        }复制代码

不过此处的addTextChangedListener是一个扩展函数,需要我们来自己实现:

inline fun TextView.addTextChangedListener(init: TextWatcherBridge.() -> Unit) = addTextChangedListener(TextWatcherBridge().apply(init))class TextWatcherBridge : TextWatcher {
private var beforeTextChanged: ((CharSequence?, Int, Int, Int) -> Unit)? = null private var onTextChanged: ((CharSequence?, Int, Int, Int) -> Unit)? = null private var afterTextChanged: ((Editable?) -> Unit)? = null override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) { beforeTextChanged?.invoke(s, start, count, after) } override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { onTextChanged?.invoke(s, start, before, count) } override fun afterTextChanged(s: Editable?) { afterTextChanged?.invoke(s) } fun beforeTextChanged(listener: (CharSequence?, Int, Int, Int) -> Unit) { beforeTextChanged = listener } fun onTextChanged(listener: (CharSequence?, Int, Int, Int) -> Unit) { onTextChanged = listener } fun afterTextChanged(listener: (Editable?) -> Unit) { afterTextChanged = listener }}复制代码

原理就是实现一个扩展函数,把我们自己实现的TextWatcherBridge加入到回调中,因为Kotlin支持函数式编程,里面都是高阶函数。为了减少性能损耗,扩展函数声明为内联函数。

转载地址:http://evwsl.baihongyu.com/

你可能感兴趣的文章
ruby on rails 删除上传后的文件
查看>>
创建uuid,备用
查看>>
JAVA POST请求(https)
查看>>
python操作excel表格
查看>>
JAVA 枚举妙用
查看>>
MySQL在线导出文件报错
查看>>
QCon所见和所得:杭州QCon热门技术话题分享
查看>>
图表(Chart & Graph)你真的用对了吗?
查看>>
做好软件项目验收管理4步走
查看>>
有关dubbo线程池溢出
查看>>
springmvc框架
查看>>
安装Spket插件到Eclipse
查看>>
学习笔记(四)——目录命令、rm 等常用命令、查看文本命令、文件属性
查看>>
Vue知识点整理
查看>>
python笔试题---实践知识点
查看>>
spring boot 2.x data redis 使用也太简单了吧
查看>>
php超时时间说明
查看>>
spring cron表达式及解析过程
查看>>
MyBatis(二)-----注解方式crud
查看>>
navicat连接腾讯云MySQL
查看>>