Android的Kotlin秘方(I):OnGlobalLayoutListener
2016-03-23 23:33
681 查看
春节后,又重新“开张”。各位高手请继续支持。谢谢!
原文标题:Kotlin recipes for Android (I): OnGlobalLayoutListener
原文链接:http://antonioleiva.com/kotlin-ongloballayoutlistener/
原文作者:Antonio Leiva(http://antonioleiva.com/about/)
原文发布:2016-03-16
Android的Kotlin秘方(I):OnGlobalLayoutListener
今天一位同伴问我怎样恰当使用OnGlobalLayoutListener,而不需要太多的模板。这是一个棘手的问题,我们需要进一步深入研究。
幸亏Kotlin提供很好的与Java互操作性,我们能够以一种非常清晰的方法 —— 使用它的模拟属性和Lambda表达式 —— 实现单一方法接口:
这里有什么问题吗?为了预防泄漏,推荐的实践是在完成使用它后,立即删除这个侦听器。但是由于使用了Lambda表达式,Lambda没有对象那么精确,我们没有对象的引用。
原方式还是可以用,但是在Kotlin中直接用匿名对象,每次都会有一只小猫死去。如果仍然需要做下面这样的事,没法改用更好开发语言:
为视图接收另一个函数创建一个新函数,由它自己创建和删除侦听器。就像这样:
现在你就可以调用这个函数,确保其自己添加和删除侦听器。除非,你永远不会忘记删除:
如果喜欢,可以用扩展ViewTreeObserver的函数,而不是直接用View。这取决你。
我还泛型该函数使它能够在任何继承View的对象中使用,也能够从编写的函数中访问所有它的指定函数和属性。
这个afterMeasured函数非常类似前者,但是在Lambda表达式内直接用视图的属性和public方法。例如,我们能够得到recycler的宽度和基于它用列的动态数组设置布局。
原文标题:Kotlin recipes for Android (I): OnGlobalLayoutListener
原文链接:http://antonioleiva.com/kotlin-ongloballayoutlistener/
原文作者:Antonio Leiva(http://antonioleiva.com/about/)
原文发布:2016-03-16
Android的Kotlin秘方(I):OnGlobalLayoutListener
今天一位同伴问我怎样恰当使用OnGlobalLayoutListener,而不需要太多的模板。这是一个棘手的问题,我们需要进一步深入研究。
OnGlobalLayoutListener是干什么的?
这个侦听器对于任何试图的ViewTreeObserver都适用,并且在已知视图宽度和高度进行各种计算、动画等等时,为扩展和测量视图常常回调它。幸亏Kotlin提供很好的与Java互操作性,我们能够以一种非常清晰的方法 —— 使用它的模拟属性和Lambda表达式 —— 实现单一方法接口:
recycler.viewTreeObserver.addOnGlobalLayoutListener { // do whatever }
这里有什么问题吗?为了预防泄漏,推荐的实践是在完成使用它后,立即删除这个侦听器。但是由于使用了Lambda表达式,Lambda没有对象那么精确,我们没有对象的引用。
原方式还是可以用,但是在Kotlin中直接用匿名对象,每次都会有一只小猫死去。如果仍然需要做下面这样的事,没法改用更好开发语言:
recycler.viewTreeObserver.addOnGlobalLayoutListener( object : ViewTreeObserver.OnGlobalLayoutListener { override fun onGlobalLayout() { recycler.viewTreeObserver.removeOnGlobalLayoutListener(this); // do whatever } });
找一个更佳替换方法
好了,既已知不要那样做。那么有什么更好的方法吗?我们被迫使用一种看上去没有那么好看的方法,但是可能是一种好的选择,将扩展函数隐藏起来。为视图接收另一个函数创建一个新函数,由它自己创建和删除侦听器。就像这样:
inline fun View.waitForLayout(crossinline f: () -> Unit) = with(viewTreeObserver) { addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { override fun onGlobalLayout() { removeOnGlobalLayoutListener(this) f() } }) }
现在你就可以调用这个函数,确保其自己添加和删除侦听器。除非,你永远不会忘记删除:
recycler.waitForLayout { // do whatever }
如果喜欢,可以用扩展ViewTreeObserver的函数,而不是直接用View。这取决你。
但是我们仍可以改进它
这是在测试视图后布局侦听器通常要做的一些事,所以需要等待宽度和高度大于0。而且可能要在视图中调用它时做一些事,这为什么不能转换参数函数到扩展函数?我还泛型该函数使它能够在任何继承View的对象中使用,也能够从编写的函数中访问所有它的指定函数和属性。
inline fun <T: View> T.afterMeasured(crossinline f: T.() -> Unit) { viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { override fun onGlobalLayout() { if (measuredWidth > 0 && measuredHeight > 0) { viewTreeObserver.removeOnGlobalLayoutListener(this) f() } } }) }
这个afterMeasured函数非常类似前者,但是在Lambda表达式内直接用视图的属性和public方法。例如,我们能够得到recycler的宽度和基于它用列的动态数组设置布局。
recycler.afterMeasured { val columnCount = width / columnWidth layoutManager = GridLayoutManager(context, columnCount) }
总结
在Android中运行时,这确实仍有些事情做的不是很好,即使是移植Kotlin,但是总是可以通过隐藏在其他结构背后的不确定因素,找到提升可读性和避免不确定因素的选择。至少,仅需要编写一次,而其它代码则非常漂亮!相关文章推荐
- Qt for Android 中集成 ShareSDK
- Android ScrollView 去掉 scrollbar 和 阴影
- android5.0+(Toolbar)
- openCv 导入 android studio
- android手势滑动关闭当前activity
- Android Studio 打包、生成jks密钥、签名Apk、多渠道打包
- 关于android从入门到精通4.1.9范例1出现的闪退的问题
- Android屏幕自适应4种解决方案
- Android 获取ROOT权限原理解析
- 使用详解及源码解析Android中的Adapter、BaseAdapter、ArrayAdapter、SimpleAdapter和SimpleCursorAdapter
- Android中一个轻量级的存储方案(SharedPreferences)
- Android之分页加载数据
- Android 使用viewpager时报Didn't find class "android.support.v4.view.Viewpager"错误
- Android在Fragment中强制隐藏输入法
- Android数据库升级、降级、创建
- 安卓view滑动控件及方法scrollBy,scrollTo的使用
- Android Support v4、v7、v13 介绍
- Android 无限滑盘控件 WheelView实现
- android-继承BaseAdapter自定义适配器基础
- ubunut 12.04 (64bit) android编译环境搭建