大家好,欢迎来到IT知识分享网。
一.apply 函数 和 run 函数
1.1 apply函数
apply函数是指在函数块内可以通过 this 指代该对象,返回值为该对象自己。在链式调用中,可以考虑使用它来不破坏链式。
/** * 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
第一个字符串是在闭包中打印的,第二个字符串是result的结果,它仍然是“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
第一个字符串是在闭包中打印的,第二个字符串是result的结果,它返回的是闭包中最后一行的值,所以也打印“Hello World”。
1.3 项目中的使用
在App的反馈页面中,需要输入邮箱、主题、内容才能完成反馈按钮的提交。
最初的写法是这样:
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 } }
感觉不够cool,可以结合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 } }
二.data class
Kotlin的data class有点类似于Scala的case class。
以下的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)
可以看到采用data class能够简化Java Bean类。我们的App采用了MVVM的架构,因此对应Model类全部使用data class。
三.无需使用findViewById 或者 butterknife
使用Kotlin Android Extensions插件即可实现该功能,它是Kotlin 插件的组成之一,无需再单独安装插件。
我们在各个modules的build.gradle中添加该插件,即可使用。
apply plugin: 'kotlin-android-extensions'
布局文件中的id,可以直接在代码中使用。
首先,按照import kotlinx.android.synthetic.main.布局文件名*的方式导入。
例如MainActivity,它的布局文件是activity_main.xml
则按照如下的方式进行import
import kotlinx.android.synthetic.main.activity_main.*
那么activity_main.xml中控件的id,可以直接在MainActivity中使用,无需使用findViewById 或者 butterknife。是不是特别方便?
四.点击事件的埋点处理
App的埋点,使用自己家的产品–魔窗的sdk来做事件的埋点。
如果使用Java来开发App,可以使用AOP来实现埋点。由于我们的App采用Kotlin编写,Kotlin可以将事件的点击简化成如下的形式
view.setOnClickListener { .... }
这种简化了的lambda表达式,所以我还是老老实实的使用传统方式进行埋点。
使用Kotlin的通常做法:
view.setOnClickListener { TrackAgent.currentEvent().customEvent(eventName) .... }
或者
view.setOnClickListener { TrackAgent.currentEvent().customEvent(eventName, trackMap) .... }
后来,我写了一个View的扩展函数click,后来经过同事的优化
目前,已经将该扩展函数放入我的Kolin的工具类库 https://github.com/fengzhizi715/SAF-Kotlin-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) { .... }
创作不易喜欢的话记得点击+关注哦
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/52279.html