春节后,又重新“开张”。各位高手请继续支持。谢谢!

原文标题: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,但是总是可以通过隐藏在其他结构背后的不确定因素,找到提升可读性和避免不确定因素的选择。至少,仅需要编写一次,而其它代码则非常漂亮!

Android的Kotlin秘方(I):OnGlobalLayoutListener的更多相关文章

  1. Android的Kotlin秘方(II):RecyclerView 和 DiffUtil

    作者:Antonio Leiva 时间:Sep 12, 2016 原文链接:http://antonioleiva.com/recyclerview-diffutil-kotlin/ 如你所知,在[支 ...

  2. [Android]使用Kotlin开发Android(二)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4829007.html [TOC] 使用Kotlin+OkHtt ...

  3. Google Android Studio Kotlin 开发环境配置

    Google 近日开发者大会宣布Kotlin成为Android开发的第一级语言,即Android官方开发语言,可见Google对Kotlin的重视,本文就介绍一下Android Studio下的Kot ...

  4. Google Android Studio Kotlin

    Google Android Studio Kotlin 开发环境配置 Google 近日开发者大会宣布Kotlin成为Android开发的第一级语言,即Android官方开发语言,可见Google对 ...

  5. [Android]使用Kotlin+Anko开发Android(一)

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/4800656.html  Kotlin是由JetBrains开发 ...

  6. 在Android中用Kotlin的Anko运行后台任务(KAD 09)

    作者:Antonio Leiva 时间:Jan 19, 2017 原文链接:https://antonioleiva.com/anko-background-kotlin-android/ Anko是 ...

  7. 让你的代码量减少3倍!使用kotlin开发Android(四) kotlin bean背后的秘密

    上一篇我们介绍了缩短五倍的java bean,不知道你在看的时候有没有一种疑问捏? 本文同步自博主的私人博客wing的地方酒馆 再来回顾一下,两种代码的对比 public class User { p ...

  8. Getting started with Android and Kotlin (译文)

    原文链接 http://kotlinlang.org/docs/tutorials/kotlin-android.html 写在前面 Kotlin 是一个基于 JVM 的新的编程语言,由 JetBra ...

  9. 在Android上Kotlin的单元测试(KAD22)

    作者:Antonio Leiva 时间:Apr 25, 2017 原文链接:https://antonioleiva.com/unit-tests-android-kotlin/ 当然,Kotlin也 ...

随机推荐

  1. Windows Server 2012 NIC Teaming介绍及注意事项

    Windows Server 2012 NIC Teaming介绍及注意事项 转载自:http://www.it165.net/os/html/201303/4799.html Windows Ser ...

  2. nginx源码分析之网络初始化

    nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...

  3. 【Machine Learning】Python开发工具:Anaconda+Sublime

    Python开发工具:Anaconda+Sublime 作者:白宁超 2016年12月23日21:24:51 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现 ...

  4. Entity Framework的启动速度优化

    最近开发的服务放到IIS上寄宿之后,遇到一些现象,比如刚部署之后,第一次启动很慢:程序放置一会儿,再次请求也会比较慢.比如第一个问题,可以解释为初次请求某一个服务的时候,需要把程序集加载到内存中可能比 ...

  5. CSS3新特性应用之结构与布局

    一.自适应内部元素 利用width的新特性min-content实现 width新特性值介绍: fill-available,自动填充盒子模型中剩余的宽度,包含margin.padding.borde ...

  6. Tableau未必最佳,国内BI也能突破重围!

    如今,百度一下商业智能或BI工具,总能看到Tableau的身影.并不是Tableau的营销做得好,而是国内对于商业智能工具的认知和选择似乎都落在了Tableau身上.导致不管业内业外都对商业智能的概念 ...

  7. MySQL全文索引 FULLTEXT索引和like的区别

    1.概要 InnoDB引擎对FULLTEXT索引的支持是MySQL5.6新引入的特性,之前只有MyISAM引擎支持FULLTEXT索引.对于FULLTEXT索引的内容可以使用MATCH()-AGAIN ...

  8. [AlwaysOn Availability Groups]健康模型 Part 1——概述

    健康模型概述 在成功部署AG之后,跟踪和维护健康状况是很重要的. 1.AG健康模型概述 AG的健康模型是基于策略管理(Policy Based Management PBM)的.如果不熟悉这个特性,可 ...

  9. 用C++实现Linux中shell的ls功能

    实现输出当前目录下的文件名 ls功能: 方法一: #include <iostream> #include <algorithm> #include <stdio.h&g ...

  10. VMware下对虚拟机Ubuntu14系统所在分区sda1进行磁盘扩容

    VMware下对虚拟机Ubuntu14系统所在分区sda1进行磁盘扩容 一般来说,在对虚拟机里的Ubuntu下的磁盘进行扩容时,都是添加新的分区,而并不是对其系统所在分区进行扩容,如在此链接中http ...