使用Kotlin高效地開發(fā)Android App(二)

一.apply 函數(shù) 和 run 函數(shù)

1.1 apply函數(shù)

apply函數(shù)是指在函數(shù)塊內(nèi)可以通過 this 指代該對象切心,返回值為該對象自己鹏氧。在鏈式調(diào)用中渤涌,可以考慮使用它來不破壞鏈式。

/**
 * 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)
    }
}

執(zhí)行結果:

Hello World
Hello

第一個字符串是在閉包中打印的把还,第二個字符串是result的結果实蓬,它仍然是“Hello”。

1.2 run函數(shù)

run函數(shù)類似于apply函數(shù)吊履,但是run函數(shù)返回的是最后一行的值安皱。

/**
 * 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)
    }
}

執(zhí)行結果:

Hello World
Hello World

第一個字符串是在閉包中打印的,第二個字符串是result的結果艇炎,它返回的是閉包中最后一行的值酌伊,所以也打印“Hello World”。

1.3 項目中的使用

在App的反饋頁面中缀踪,需要輸入郵箱居砖、主題、內(nèi)容才能完成反饋按鈕的提交驴娃。

最初的寫法是這樣:

        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函數(shù)

       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函數(shù)一起使用

        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插件即可實現(xiàn)該功能厚棵,它是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的埋點,使用自己家的產(chǎn)品--魔窗的sdk來做事件的埋點炼杖。

如果使用Java來開發(fā)App灭返,可以使用AOP來實現(xiàn)埋點。由于我們的App采用Kotlin編寫坤邪,Kotlin可以將事件的點擊簡化成如下的形式

        view.setOnClickListener {
             ....
        }

這種簡化了的lambda表達式熙含,所以我還是老老實實的使用傳統(tǒng)方式進行埋點。

使用Kotlin的通常做法:

        view.setOnClickListener {

             TrackAgent.currentEvent().customEvent(eventName)
             ....
        }

或者

        view.setOnClickListener {

             TrackAgent.currentEvent().customEvent(eventName, trackMap)
             ....
        }

后來艇纺,我寫了一個View的擴展函數(shù)click怎静,后來經(jīng)過同事的優(yōu)化

目前,已經(jīng)將該擴展函數(shù)放入我的Kolin的工具類庫 https://github.com/fengzhizi715/SAF-Kotlin-Utils

此時黔衡,埋點的代碼變成這樣

        view.click {

             TrackAgent.currentEvent().customEvent(eventName)
             ....
        }

或者

        view.click {

             TrackAgent.currentEvent().customEvent(eventName, trackMap)
             ....
        }

進一步的優(yōu)化處理消约,對于View增加擴展函數(shù)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) {
            ....
        }

喜歡點擊+關注哦

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末员帮,一起剝皮案震驚了整個濱河市或粮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌捞高,老刑警劉巖氯材,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異硝岗,居然都是意外死亡氢哮,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門型檀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來冗尤,“玉大人,你說我怎么就攤上這事×哑撸” “怎么了皆看?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長背零。 經(jīng)常有香客問我腰吟,道長,這世上最難降的妖魔是什么徙瓶? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任毛雇,我火速辦了婚禮,結果婚禮上侦镇,老公的妹妹穿的比我還像新娘灵疮。我一直安慰自己昼牛,他們只是感情好拯田,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著瞭郑,像睡著了一般氮趋。 火紅的嫁衣襯著肌膚如雪伍派。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天剩胁,我揣著相機與錄音诉植,去河邊找鬼。 笑死昵观,一個胖子當著我的面吹牛晾腔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播啊犬,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼灼擂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了觉至?” 一聲冷哼從身側(cè)響起剔应,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎语御,沒想到半個月后峻贮,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡应闯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年纤控,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碉纺。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡船万,死狀恐怖刻撒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情耿导,我是刑警寧澤声怔,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站碎节,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏抵卫。R本人自食惡果不足惜狮荔,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望介粘。 院中可真熱鬧殖氏,春花似錦、人聲如沸姻采。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽慨亲。三九已至婚瓜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間刑棵,已是汗流浹背巴刻。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蛉签,地道東北人胡陪。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像碍舍,于是被迫代替她去往敵國和親柠座。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容