以下通过AlertDialog
构建使用案例
创建AlertDialog.Builder()
val builder = AlertDialog.Builder(this)
let()
为了方便省去确定、取消按钮
builder.let {
it.setTitle("Dialog title")
it.setMessage("Dialog message")
it.setCancelable(false)
it.show()
}
看上去和java的链式调用并无很大区别,也省略不了多少代码。实则当调用let函数的对象为可空类型时更加方便,相当于少写一个if != null
的判断。使用场景为单个对象的多次方法调用,可空对象使用起来更加舒适。
builder?.let {
it.setTitle("Dialog title")
it.setMessage("Dialog message")
it.setCancelable(false)
it.show()
}
点进去看let函数实现
public inline fun <T, R> T.let(block: (T) -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block(this)
}
let函数是T类型的扩展函数,任意对象都可调用。参数为lambda,将调用者对象T传到lambda,所以lambda中it指向调用者,函数返回值即lambda返回值。
run()
public inline fun <T, R> T.run(block: T.() -> R): R {
return block()
}
与let函数的区别在于参数block: T.() -> R
是带接收者的lambda,lambda内部this指向接收者T。
builder.run {
setTitle("Dialog title")
setMessage("Dialog message")
setCancelable(false)
show()
}
相较于let函数,省略了it,适用于任何let函数使用的场景。
also()
public inline fun <T> T.also(block: (T) -> Unit): T {
block(this)
return this
}
与let函数的区别:函数的返回值为T,即调用者本身。适用于任何let函数使用的场景,并且返回调用者对象本身。
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函数的区别:block: T.() -> Unit
带接收者的lambda,可省略it。适用于任何also函数使用的场景。
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函数有两个参数,T和带有接收者T的lambda。return receiver.block()
函数内部T调用了lambda,函数返回值为lambda返回值;等同于run函数,只是写法稍有区别。
with(builder){
setTitle("Dialog title")
setMessage("Dialog message")
setCancelable(false)
show()
}
配合扩展函数使用
定义两个扩展函数
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中调用
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initDialog {
setTitle("Dialog title")
setMessage("Dialog message")
setCancelable(false)
show()
}
}