原文标题:Functional operations over Views in ViewGroup using Kotlin

原文链接:http://antonioleiva.com/functional-operations-viewgroup-kotlin/

原文作者:Antonio Leiva(http://antonioleiva.com/about/)

原文发布:2015-07-29

集合、迭代、数组、序列 ... 所有这些共用一套好用的函数,这组函数可帮助对它们的元素进行转换、排序以及其它操作。但是,由于类的构造方法,在Android SDK中,有部分函数还不能用。

例如,我们不能直接获得ViewGroup内部视图列表,所以这些操作是不可能使用的。但是并非所有一切都失去了。在Kotlin中,我们有方法为这些操作准备任何数据。诀窍简单:我们只需要创建一个Sequence。在我们的例子中,Sequence将是一组有序的View。我们只需要实现一个函数,其返回Iterator

如果我们有了Sequence,函数式操作领域就为我们打开了使用它们的大门。所以让我们从它开始。

注:阅读文章结尾

如lakedaemon666在评论中所建议的那样,有一个不用Sequence的更简单的方法可以获得同样的结果。我会保留原文记录,但是建议你看看替代的解决方案。

创建ViewGroup的Sequence

如前所述,我们将创建迭代器(iterator),它必须知道是否有下一项,下一项是哪个。我们还创建一个扩展函数,为了任何 ViewGroup 和继承类提供一个简单的方法做那项工作:

 1 fun ViewGroup.asSequence(): Sequence<View> = object : Sequence<View> {
 2
 3     override fun iterator(): Iterator<View> = object : Iterator<View> {
 4         private var nextValue: View? = null
 5         private var done = false
 6         private var position: Int = 0
 7
 8         override public fun hasNext(): Boolean {
 9             if (nextValue == null && !done) {
10                 nextValue = getChildAt(position)
11                 position++
12                 if (nextValue == null) done = true
13             }
14             return nextValue != null
15         }
16
17         override fun next(): View {
18             if (!hasNext()) {
19                 throw NoSuchElementException()
20             }
21             val answer = nextValue
22             nextValue = null
23             return answer!!
24         }
25     }
26 }

检索视图递归列表

获得一个视图列表,并对其进行函数操作是非常有用的。因此,我们可以先创建顶层视图列表,然后,用它以递归方式逐级检索ViewGroup中视图。

让我们为ViewGroup创建新扩展属性。扩展属性非常类似扩展函数,可用于任何类:

1 public val ViewGroup.views: List<View>
2     get() = asSequence().toList()

我们可以用这,创建递归函数,它返回布局中任何ViewGroup内部的所有View

1 public val ViewGroup.viewsRecursive: List<View>
2     get() = views flatMap {
3         when (it) {
4             is ViewGroup -> it.viewsRecursive
5             else -> listOf(it)
6         }
7     }

flatMap,我们把全部结果的多个列表转换到一个列表中。它将遍历任何视图;如果是ViewGroup,它还会遍历自己的视图。否则,就返回仅有一项的列表。

用法实例

现在,我们得到viewRecursive属性,执行我们想要的任何操作。这里你可以看到两个例子。我创建这样一个简单的布局:

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2                 xmlns:tools="http://schemas.android.com/tools"
 3                 android:id="@+id/container"
 4                 android:layout_width="match_parent"
 5                 android:layout_height="match_parent"
 6                 android:paddingBottom="@dimen/activity_vertical_margin"
 7                 android:paddingLeft="@dimen/activity_horizontal_margin"
 8                 android:paddingRight="@dimen/activity_horizontal_margin"
 9                 android:paddingTop="@dimen/activity_vertical_margin"
10                 tools:context=".MainActivity">
11
12     <TextView
13         android:layout_width="wrap_content"
14         android:layout_height="wrap_content"
15         android:text="@string/hello_world"/>
16
17     <FrameLayout
18         android:layout_width="match_parent"
19         android:layout_height="wrap_content"
20         android:layout_centerInParent="true">
21
22         <TextView
23             android:layout_width="wrap_content"
24             android:layout_height="wrap_content"
25             android:text="Hello Java"/>
26
27         <TextView
28             android:layout_width="wrap_content"
29             android:layout_height="wrap_content"
30             android:layout_gravity="center_horizontal"
31             android:text="Hello Kotlin"/>
32
33         <TextView
34             android:layout_width="wrap_content"
35             android:layout_height="wrap_content"
36             android:layout_gravity="end"
37             android:text="Hello Scala"/>
38
39     </FrameLayout>
40
41     <LinearLayout
42         android:layout_width="match_parent"
43         android:layout_height="wrap_content"
44         android:layout_alignParentBottom="true"
45         android:orientation="horizontal">
46
47         <CheckBox
48             android:layout_width="wrap_content"
49             android:layout_height="wrap_content"
50             android:text="Check 1"/>
51
52         <CheckBox
53             android:layout_width="wrap_content"
54             android:layout_height="wrap_content"
55             android:text="Check 2"/>
56
57         <CheckBox
58             android:layout_width="wrap_content"
59             android:layout_height="wrap_content"
60             android:text="Check 3"/>
61
62         <CheckBox
63             android:layout_width="wrap_content"
64             android:layout_height="wrap_content"
65             android:text="Check 4"/>
66
67     </LinearLayout>
68
69 </RelativeLayout>

例如,在MainActivity.onCreate()中,可应用这段代码。它将Hello Kotlin!串转换为大写字母,选中偶数复选框:

 1 val container: ViewGroup = find(R.id.container)
 2 val views = container.viewsRecursive
 3
 4 // Set Kotlin TextView to Upper
 5 val kotlinText = views.first {
 6     it is TextView && it.text.toString().contains("Kotlin")
 7 } as TextView
 8 kotlinText.text = kotlinText.text.toString().toUpperCase()
 9
10 // Set even checkboxes as checked, and odd as unchecked
11 views filter {
12     it is CheckBox
13 } forEach {
14     with(it as CheckBox) {
15         val number = text.toString().removePrefix("Check ").toInt()
16         setChecked(number % 2 == 0)
17     }
18 }

替代的解决方案

如lakedaemon666在评论中所提及的那样(谢谢解释),如果之后我们遍历整个sequence,那么创建sequence就没有什么意义了。例如,当按行读取文件时,sequence是懒惰迭代。只有要求必要的项目。而我们却要使用所有项,所以简单的列表就足够了。

另外,有许多简单的方法可以产生视图列表。我们可以依赖值域产生视图的索引列表,将它们映射到我们需要的视图列表中。所有这一切就一行:

1 public val ViewGroup.views: List<View>
2     get() = (0..getChildCount() - 1) map { getChildAt(it) }

总结

这是个无聊的例子,但是这个概念或许可使你的所有代码函数化,停止依靠那些典型迭代式编程的循环和其它控制流。

记住从我写的书《Android开发者的Kotlin》中,你能够学习到Kotlin的这点以及许多其它能力,你将通过从0开始创建Android APP学习Kotlin。

转载于:https://www.cnblogs.com/figozhg/p/5017316.html

使用Kotlin对ViewGroup的视图进行函数使操作相关推荐

  1. [译]Effective Kotlin系列之探索高阶函数中inline修饰符(三)

    简述: 不知道是否有小伙伴还记得我们之前的Effective Kotlin翻译系列,之前一直忙于赶时髦研究Kotlin 1.3中的新特性.把此系列耽搁了,赶完时髦了还是得踏实探究本质和基础,从今天开始 ...

  2. 【转】简单介绍几个CDS视图聚合函数

    今天简单介绍几个CDS视图聚合函数. 1.SUM 代码举例如下: @AbapCatalog.sqlViewName: 'ZCDS_AGGR' @AbapCatalog.compiler.compare ...

  3. Kotlin实践(3)-入口 函数

    main函数是kotlin程序的入口,print函数可向标准输出打印文本,但不打印行结束符,而println函数可以向标准输出打印文本,并换行. fun main() {println("我 ...

  4. 超详细图解!【MySQL进阶篇】存储过程,视图,索引,函数,触发器

    超详细图解![MySQL进阶篇]存储过程,视图,索引,函数,触发器 1.1 下载Linux 安装包 1.2 安装MySQL 1.3 启动 MySQL 服务 1.4 登录MySQL 2\. 索引 2.1 ...

  5. Kotlin学习笔记 第三章 函数 高阶函数 lambda表达式 内联函数

    参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...

  6. (五)Kotlin简单易学 基础语法-初始函数(下)

    (五)Kotlin简单易学 基础语法-初始函数(下) 函数内联 ➢ lambda可以让你更灵活的编写应用,但是,灵活也要付出代价的. ➢在JVM上,你定义的lambda会以对象实例的形式存在,JVM会 ...

  7. 为视图或函数指定的列名比其定义中的列多

    今天上班的时候,发现昨天写的一个功能无法正常获得数据,找了很久,才发现是其他同事动过功能视图所查询的的基本表结构. 情况: 有视图A,视图B,视图B查询视图A的数据,并且使用*代替列名,更新视图A中的 ...

  8. SQL Server 为视图或函数 指定的列名比其定义中的列多

    问题:com.microsoft.sqlserver.jdbc.SQLServerException: 为视图或函数 指定的列名比其定义中的列多. 原因:因为修改了表字段(新增.移除.修改),并且视图 ...

  9. Kotlin 编程核心基石—高阶函数

    前言 1. 高阶函数有多重要? 高阶函数,在 Kotlin 里有着举足轻重的地位.它是 Kotlin 函数式编程的基石,它是各种框架的关键元素,比如:协程,Jetpack Compose,Gradle ...

最新文章

  1. RepVGG:极简架构,SOTA性能,论文解读
  2. PE文件和COFF文件格式分析——RVA和RA相互计算
  3. 剑指offer:数组中重复的数字
  4. python为什么不能以数字开头_python变量为什么不能以数字开头
  5. OSPF——优化技术(含配置)
  6. linux 内存查看_Linux终端查看最消耗CPU内存的进程
  7. oracle创建默认序列号,PLS-00103:为序列号oracle创建触发器(PLS-00103: Create trigger for sequence number oracle)...
  8. 2019年税收分类编码_您如何在2019年学习编码
  9. NDS程序开发可行性分析报告
  10. 数据结构入门(2)——线性表、堆栈和队列
  11. openCV获取和修改像素值
  12. JEESZ分布式框架简介---技术介绍文档
  13. 【Linux】Linux 磁盘与文件系统管理命令
  14. ORACLE MERGE INTO语句,unable to get a stable set of rows in the source tables报错解决
  15. 推荐2个适合程序员使用的显示器
  16. 继续分享一些基础的Python编程2
  17. php qq登陆网站实例代码,QQ登陆网站实例代码
  18. 成都电子科技大学深圳校区计算机学院导师简介
  19. 三.基础部分+asp网站搭建
  20. android屏幕适配:一个很棒的屏幕适配文章

热门文章

  1. 网络推广——网络推广专员从多角度分析网站关键词排名受影响因素
  2. 开展企业网站建设如何做到保质保量?
  3. 写出python中的六种数据类型_python 数据类型1
  4. python函数代码的复用_Python__函数和代码复用
  5. android调用文件管理打开某个路径,安卓 通过intent调用系统文件管理器打开指定路径目录...
  6. decode函数_decode函数的妙用网友的两个问题解答
  7. Android 机型适配之gradient默认渐变方向
  8. angular学习笔记(三十)-指令(4)-transclude
  9. 深入理解$watch ,$apply 和 $digest --- 理解数据绑定过程——续
  10. Mybatis优缺点