Code前端首页关于Code前端联系我们

Kotlin有效开发Android应用程序(2)

terry 2年前 (2023-09-22) 阅读数 71 #移动小程序

1。 Apply函数和

run函数,apply和run函数,都是来自Kotlin标准库的函数。第一篇文章中已经介绍过。

1.1 应用函数

应用是指功能块内可以引用对象,返回值是对象本身。对于链式调用,您可以考虑使用它来避免破坏链。

/**
 * Calls the specified function [block] with `this` value as its receiver and returns `this` value.
 */
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block()
    return this
}
复制代码

例如:

/**
 * Created by tony on 2018/4/26.
 */
object Test {

    @JvmStatic
    fun main(args: Array<String>) {

        val result ="Hello".apply {


            println(this+" World")

            this+" World"
        }

        println(result)
    }
}
复制代码

执行结果:

Hello World
Hello
复制代码

第一个字符串在闭包中输入,第二个字符串是结果的结果,仍然是“Hello”。

1.2 run函数

run函数与apply函数类似,但run函数返回最后一行的值。

/**
 * Calls the specified function [block] with `this` value as its receiver and returns its result.
 */
@kotlin.internal.InlineOnly
public inline fun <T, R> T.run(block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
}
复制代码

例如:

/**
 * Created by tony on 2018/4/26.
 */
object Test {

    @JvmStatic
    fun main(args: Array<String>) {

        val result ="Hello".run {


            println(this+" World")

            this + " World"
        }

        println(result)
    }
}
复制代码

执行结果:

Hello World
Hello World
复制代码

第一个字符串是在闭包中输入的,第二个字符串是结果的结果,它返回闭包最后一行的值,所以“还打印了“Hello World”。

1.3 在项目中使用

在应用程序的反馈页面中,您必须输入电子邮件地址、主题和内容,才能完成反馈按钮的提交。

原来的拼写如下:

        if (viewModel.email.value!!.isEmpty()) {
            toast(resources.getString(R.string.you_have_not_completed_the_email_address)).show()
            return@onClickRight
        }
        if (!Util.checkEmail(viewModel.email.value!!)) {
            toast(resources.getString(R.string.the_email_format_you_have_filled_is_incorrect)).show()
            return@onClickRight
        }
        if (viewModel.subject.value!!.isEmpty()) {
            toast(resources.getString(R.string.you_have_not_completed_the_feedback_subject)).show()
            return@onClickRight
        }
        if (viewModel.content.value!!.isEmpty()) {
            toast(resources.getString(R.string.you_have_not_completed_the_details)).show()
            return@onClickRight
        }
复制代码

改一下,让它只使用Apply函数

       viewModel.apply {

            if (email.value!!.isEmpty()) {
                toast(resources.getString(R.string.you_have_not_completed_the_email_address)).show()
                return@onClickRight
            }
            if (!Util.checkEmail(email.value!!)) {
                toast(resources.getString(R.string.the_email_format_you_have_filled_is_incorrect)).show()
                return@onClickRight
            }
            if (subject.value!!.isEmpty()) {
                toast(resources.getString(R.string.you_have_not_completed_the_feedback_subject)).show()
                return@onClickRight
            }
            if (content.value!!.isEmpty()) {
                toast(resources.getString(R.string.you_have_not_completed_the_details)).show()
                return@onClickRight
            }
        }
复制代码

看起来不够酷,可以和run、apply函数一起使用

        viewModel.email.run {

            if (value!!.isEmpty()) {
                toast(resources.getString(R.string.you_have_not_completed_the_email_address)).show()
                return@onClickRight
            }
            if (!Util.checkEmail(value!!)) {
                toast(resources.getString(R.string.the_email_format_you_have_filled_is_incorrect)).show()
                return@onClickRight
            }

            viewModel
        }.subject.run {

            if (value!!.isEmpty()) {
                toast(resources.getString(R.string.you_have_not_completed_the_feedback_subject)).show()
                return@onClickRight
            }

            viewModel
        }.content.apply {

            if (value!!.isEmpty()) {
                toast(resources.getString(R.string.you_have_not_completed_the_details)).show()
                return@onClickRight
            }
        }
复制代码

2。数据类

Kotlin 的数据类与 Scala 的案例类有些相似。

以下 Java Bean 代码

/**
 * Created by tony on 2018/4/27.
 */
public class User {

    public String userName;
    public String password;
}
复制代码

相当于

data class User (var userName: String? = null,var password: String? = null)
复制代码

。可见,使用数据类可以简化Java Bean类。我们的应用程序使用MVVM架构,因此所有相应的模型类都使用数据类。

3。无需使用 findViewById 或 butterknife

使用 Kotlin Android 扩展插件即可使用此功能。它是Kotlin插件的一个组件,不需要单独安装插件。

将插件添加到每个模块的 build.gradle 中,即可使用。

apply plugin: 'kotlin-android-extensions'
复制代码

布局文件中的标识符可以直接在代码中使用。首先将其导入为 kotlinx.android.synthetic.main.layout 文件名*。

比如MainActivity,它的布局文件是activity_main.xml,那么导入如下

import kotlinx.android.synthetic.main.activity_main.*
复制代码

然后就可以在MainActivity中直接使用activity_main.xml的控制器ID了,不需要使用findViewById或者butterknife。是不是特别舒服?

4。点击事件的埋点处理

对于应用程序的埋点,使用自己的产品——Magic Window的SDK来埋点事件。

如果使用Java开发应用程序,可以使用AOP来实现埋葬。由于我们的应用程序是 Kotlin 编写的,Kotlin 可以将事件点击简化为以下形式:

        view.setOnClickListener {
             ....
        }
复制代码

这是简化的 lambda 表达式,所以我继续使用传统方法来掩盖要点。

使用Kotlin常用的做法:

        view.setOnClickListener {

             TrackAgent.currentEvent().customEvent(eventName)
             ....
        }
复制代码

        view.setOnClickListener {

             TrackAgent.currentEvent().customEvent(eventName, trackMap)
             ....
        }
复制代码

后来我写了一个点击查看扩展功能,后来被同事优化了。可以看简书这篇文章,利用扩展功能优雅地实现“防重复点击”

目前Kolin工具箱已经添加了扩展功能https://github.com/fengzhizi715/SAF-Putyin-Utils

隐藏代码变为:

        view.click {

             TrackAgent.currentEvent().customEvent(eventName)
             ....
        }
复制代码

        view.click {

             TrackAgent.currentEvent().customEvent(eventName, trackMap)
             ....
        }
复制代码

为了进一步优化,在View中添加了clickWithTrack扩展函数,专门针对隐藏点的点击事件。

package cn.magicwindow.core.ext

import android.view.View
import cn.magicwindow.TrackAgent
import com.safframework.ext.clickWithTrigger

/**
 *
 * @FileName:
 *          cn.magicwindow.core.ext.ViewExt.java
 * @author: Tony Shen
 * @date: 2018-04-24 17:17
 * @version V1.0 <描述当前版本功能>
 */

fun <T : View> T.clickWithTrack(eventName: String, time: Long = 600, block: (T) -> Unit) = this.clickWithTrigger(time) {

    TrackAgent.currentEvent().customEvent(eventName)
    block(it as T)
}

fun <T : View> T.clickWithTrack(eventName: String, trackMap: HashMap<String, String>, time: Long = 600, block: (T) -> Unit) = this.clickWithTrigger(time) {

    TrackAgent.currentEvent().customEvent(eventName, trackMap)
    block(it as T)
}
复制代码

目前可以使用

        view.clickWithTrack(key) {
            ....
        }
复制代码

        view.clickWithTrack(key,trackMap) {
            ....
        }
复制代码

总结

Kotlin有很多语法糖。使用这些语法糖可以简化你的代码并更优雅地实现功能。

作者:托尼沈哲
链接:https://juejin.im/post/5ae31d85518825671c0e4b83
来源:掘金版权所有。商业转载请联系作者获得许可。非商业转载请注明来源。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门