以下通過AlertDialog
構(gòu)建使用案例
創(chuàng)建AlertDialog.Builder()
val builder = AlertDialog.Builder(this)
let()
為了方便省去確定梭伐、取消按鈕
builder.let {
it.setTitle("Dialog title")
it.setMessage("Dialog message")
it.setCancelable(false)
it.show()
}
看上去和java的鏈?zhǔn)秸{(diào)用并無很大區(qū)別痹雅,也省略不了多少代碼。實則當(dāng)調(diào)用let函數(shù)的對象為可空類型時更加方便糊识,相當(dāng)于少寫一個if != null
的判斷绩社。使用場景為單個對象的多次方法調(diào)用,可空對象使用起來更加舒適赂苗。
builder?.let {
it.setTitle("Dialog title")
it.setMessage("Dialog message")
it.setCancelable(false)
it.show()
}
點進去看let函數(shù)實現(xiàn)
public inline fun <T, R> T.let(block: (T) -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block(this)
}
let函數(shù)是T類型的擴展函數(shù)愉耙,任意對象都可調(diào)用。參數(shù)為lambda拌滋,將調(diào)用者對象T傳到lambda劲阎,所以lambda中it指向調(diào)用者,函數(shù)返回值即lambda返回值鸠真。
run()
public inline fun <T, R> T.run(block: T.() -> R): R {
return block()
}
與let函數(shù)的區(qū)別在于參數(shù)block: T.() -> R
是帶接收者的lambda悯仙,lambda內(nèi)部this指向接收者T。
builder.run {
setTitle("Dialog title")
setMessage("Dialog message")
setCancelable(false)
show()
}
相較于let函數(shù)吠卷,省略了it锡垄,適用于任何let函數(shù)使用的場景。
also()
public inline fun <T> T.also(block: (T) -> Unit): T {
block(this)
return this
}
與let函數(shù)的區(qū)別:函數(shù)的返回值為T祭隔,即調(diào)用者本身货岭。適用于任何let函數(shù)使用的場景,并且返回調(diào)用者對象本身疾渴。
val builder = builder.also {
it.setTitle("Dialog title")
it.setMessage("Dialog message")
it.setCancelable(false)
it.show()
}
apply()
public inline fun <T> T.apply(block: T.() -> Unit): T {
block()
return this
}
與also函數(shù)的區(qū)別:block: T.() -> Unit
帶接收者的lambda千贯,可省略it。適用于任何also函數(shù)使用的場景搞坝。
val builder = builder.apply {
setTitle("Dialog title")
setMessage("Dialog message")
setCancelable(false)
show()
}
with()
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
return receiver.block()
}
with函數(shù)有兩個參數(shù)搔谴,T和帶有接收者T的lambda。return receiver.block()
函數(shù)內(nèi)部T調(diào)用了lambda桩撮,函數(shù)返回值為lambda返回值敦第;等同于run函數(shù)峰弹,只是寫法稍有區(qū)別。
with(builder){
setTitle("Dialog title")
setMessage("Dialog message")
setCancelable(false)
show()
}
配合擴展函數(shù)使用
定義兩個擴展函數(shù)
inline fun Activity.initDialog(block: AlertDialog.Builder.() -> Unit) =
AlertDialog.Builder(this).run { block(this) }
inline fun Fragment.initDialog(block: AlertDialog.Builder.() -> Unit) = this.context?.run {
AlertDialog.Builder(this).run { block(this) }
}
Activity中調(diào)用
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initDialog {
setTitle("Dialog title")
setMessage("Dialog message")
setCancelable(false)
show()
}
}