我正在尝试首次使用Kotlin构建Android应用程序。
我想在OnCreate方法之外的某些按钮上声明,我只能使用findViewById在这个函数内初始化它们。
我可以在简单而干净的代码中声明,例如java吗?
private Button btnProceed;
因为在将其转换为Kotlin时,它看起来像:
private var btnProceed: Button? = null
然后在初始化OnClick函数时需要添加!签名:
btnProceed!!.setOnClickListener
什么是正确和最干净的方式?
答案 0 :(得分:18)
这是lateinit
的一个很好的用例。标记属性lateinit
允许您使其不可为空,但在调用Activity的构造函数时不为其赋值。它恰好适用于像Activities这样的类,当初始化发生在一个单独的初始化方法中时,晚于正在运行的构造函数(在本例中为onCreate
)。
private lateinit var btnProceed: Button
如果在为其分配实际值之前读取属性,它将在运行时抛出异常 - 通过使用lateinit
,您将在首次访问它之前负责初始化它
否则,如果您希望编译器保证为您提供安全访问,则默认情况下可以使转换器执行Button
为空。而不是转换器经常使用的不安全的!!
operator,您应该使用访问该属性的safe call operator:
btnProceed?.setOnClickListener { ... }
如果btnProceed
是非空值,这将进行常规调用,否则不执行任何操作。
最后一点,您可以查看Kotlin Android Extensions,如果它适用于您的项目,则无需为View
创建属性。
答案 1 :(得分:11)
您也可以执行lazy initialization:
,而不是使用lateinit
private val button by lazy {
findViewById(R.id.button) as Button
}
第一次访问button
属性时,它将执行一次块并将结果用于将来的调用。例如,在onCreate
中,您现在可以直接访问它:
fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(bundle)
setContentView(R.layout.my_view)
button.setOnClickListener { ... }
}
答案 2 :(得分:1)
您可以使用lateinit
执行此操作,因为@ zsmb13建议但是这样做的缺点是您的视图将是可变的而不是最终的。如果您希望它们是最终版,您可以使用lazy
property delegation
通过使用lazy
,您可以声明在首次尝试访问它时如何初始化值,以便声明
private val btnProceed: Button by lazy {
findViewById(R.id.yourID)
}
每当您访问btnProceed
时,您都会加载您的活动(此示例假设您正在使用某项活动),以便您可以使用该方法