zoukankan      html  css  js  c++  java
  • Kotlin的扩展函数:扩展Android框架(KAD 08)

    作者:Antonio Leiva

    时间:Jan 11, 2017

    原文链接:https://antonioleiva.com/extension-functions-kotlin/

    扩展函数是Kotlin提供的非常酷的特性,在编写Android应用程序时,你将发现自己会大量使用它。

    我们必须承认Android框架有时做些事有点困难,在Java中我们唯一的解决方案是把我们要做事封装起来,或利用可读性差的类静态方法。

    你想怎样才能加额外函数到框架类?这就是Kotlin扩展函数允许我们做的。

    Kotlin扩展函数

    如其名称所隐含的,扩展函数是一种函数,它帮助我们扩展类功能,而无需涉及它们的代码。现在让我们来看怎样定义这些函数,以及一些我个人认为非常有用的例子。

    怎样定义扩展函数?

    就如同你平常编写函数那样,在分隔点之前放置类名称。这些函数可以放在任何位置上,不过通常在一个扩展(Extensions)文件,这个扩展文件甚至不需要包含一个类。

    一个非常简单的例子,我们要视图有visible(),使它可见。我们这样编写:

    1 fun View.visible() {
    2     this.visibility = View.VISIBLE
    3 }

    如你所见,使用该类的功能和属性时,我加上this保留字,就像我们是在类内部,但是你也可以省略:

    1 fun View.visible() {
    2     visibility = View.VISIBLE
    3 }

    一些有趣的例子

    我来说明两三个我喜欢的例子,它们很好的展示了扩展函数的能力。

    第一个有用的例子是你在扩展(inflate)视图内的适配器。通常你这样用:

    1 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    2     val v = LayoutInflater.from(parent.context).inflate(R.layout.view_item, parent, false)
    3     return ViewHolder(v)
    4 }

    在扩展(inflate)视图的代码行中使用了parent,太复杂了,并且99%时间里通常与任何其它适配器相同。为什么不给ViewGroups扩展视图的能力?

    1 fun ViewGroup.inflate(layoutRes: Int): View {
    2     return LayoutInflater.from(context).inflate(layoutRes, this, false)
    3 }

    现在你可以在上面的代码使用它:

    1 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    2     val v = parent.inflate(R.layout.view_item)
    3     return ViewHolder(v)
    4 }

    一个使用图像的非常类似例子也可以这样做。例如,如果你使用Picasso库,你需要典型的构建器加载图像:

    1 Picasso.with(imageView.context).load(url).into(imageView)

    你想要如何能够告知ImageView自己加载URL吗?

    1 fun ImageView.loadUrl(url: String) {
    2     Picasso.with(context).load(url).into(this)
    3 }
    4  
    5 imageView.loadUrl(url)

    扩展属性

    就像你能够扩展函数一样,同理也能处理属性。你需要记住的就一件事,扩展属性不能保存状态,而且需要用已有函数请求或更改对象的状态:

    1 val ViewGroup.children: List
    2     get() = (0..childCount -1).map { getChildAt(it) }

    这个属性由ViewGroup的children中取出。

    现在你就可以直接替代他们:

    1 parent.children.forEach { it.visible() }

    注意

    it是一个保留字,当函数仅有一个输入值时,用于访问函数的输入值。如我们在其他文章所读到,你可以命名那些输入值,当有多个输入值时,在Lambda表达式左边写上par。

    结论

    利用扩展函数和扩展属性,你可以扩展任何类(即使你没有访问其代码),而且如同它们是类的一部分一样使用那些扩展函数和属性。你将看到的唯一的事就是使用导入一个额外的文件。

    如果你喜欢Kotlin,要进一步的学习,建议阅读《Android开发者的Kotlin》一书,在书中我介绍这点和你在Android应用程序开发期间的许多事情。

  • 相关阅读:
    MySQL关于check约束无效的解决办法
    关于constraint的用法
    MySQL关于Duplicate entry '1' for key 'PRIMARY'错误
    iOS实现高斯模糊效果(Swift版本)
    iOS获取视频中的指定帧的两种方法
    Java关于e.printStackTrace()介绍
    iOS关于JSONKit解析Unicode字符内容出错,问题出在u0000
    Java转型(向上转型和向下转型)
    添加删除Windows组件里没有IIS(Internet信息服务)项的解决方法
    Windows2003:“无法加载安装程序库wbemupgd.dll
  • 原文地址:https://www.cnblogs.com/figozhg/p/6278624.html
Copyright © 2011-2022 走看看