kotlin - 防止 lambda 捕获使用 kotlin 合成访问的视图

Fra*_*nka 6 android android-view findviewbyid kotlin kotlin-android-extensions

我使用 Kotlin Android Extensions 插件从 XML 访问视图。如果我理解正确的话,为视图生成的合成属性可以为空,更准确地说 - 它们的类型是View!,这意味着它们可以在 Kotlin 中被视为非空,但实际上它们仍然可以为空,因为在幕后findViewById是调用,它来自 Java,所以 Kotlin 不能确保空安全。这没关系,因为我们可以使用?.运算符。

当您需要在 lambda 中使用这些时,问题就出现了,因为空值被捕获并且您永远没有机会处理非空值。

看这两个片段。在这些被执行的那一刻,view1非空,但view2为空:

//this one crashes
view1.setOnClickListener {
    view2.doStuff()
}
//this one works
view1.setOnClickListener {
    findViewById<View>(R.id.view2).doStuff()
}
Run Code Online (Sandbox Code Playgroud)

在第一种情况下发生的情况是,当执行该行时,view2为空,而 lambda 将其捕获为空。因此,即使view2lambda 运行(view1被点击)时不再为空,应用程序也会崩溃。

在第二种情况下,lambda 不捕获任何内容,因此即使view2最初为空,每次 lambda 运行(view1单击)时都会再次检索它。

所以问题是:如何在 lambdas 中使用合成属性,而不捕获初始值?

谢谢!