现在有很多Android开发的小伙伴使用Kotlin开发应用了,今天小编在使用Kotlin开发的时候遇到个问题,就是在TextView赋值时候出现了java.lang.IllegalStateException: tv must not be null
的错误,就有点纠结为什么为空。
import android.annotation.SuppressLint
import android.app.DatePickerDialog
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val time = findViewById(R.id.tv)
btn.setOnClickListener {
DatePickerDialog(this).run {
show()
setOnDateSetListener { datePicker, _, _, _ ->
tv.text = datePicker.year.toString() + (datePicker.month + 1) + datePicker.dayOfMonth
}
}
}
}
}
正常的代码逻辑是没有错误的,但是意外就发生了,在选中日期的进行数据回调就炸了。于是我稍微做了点改变
tv?.text = datePicker.year.toString() + (datePicker.month + 1) + datePicker.dayOfMonth
修改成这样,没有报错,但是也没有赋值。很难受,一直没有搞定为什么没有赋值,为什么没有爆错。[黑人问号]
我一直摸不着头脑,我出错的地方在哪里。有幸请教一位大佬,大佬原话如下:
使用kotlinx.android直接使用控件id时要注意,如果是在dialog, fragment等对象的run 或apply里面,使用控件id,它调用的是this即dialog或fragment里的,也就是它是在dialog或fragment里去找这个id对应的控件,而不是外面的activity,所以会出现这个控件为空。
你可以在外面声明个临时变量,比如
val date = tv
然后在里面使用date而不是tv
或者使用let之类的方法而不是run或apply
@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val time = findViewById(R.id.tv)
btn.setOnClickListener {
DatePickerDialog(this).run {
show()
setOnDateSetListener { datePicker, _, _, _ ->
time.text = datePicker.year.toString() + (datePicker.month + 1) + datePicker.dayOfMonth
}
}
}
}
我初始化的组件之后,我在dialog里面找到这个组件,然后在activity中赋值成功。成功解决了上面说的问题,很感谢大佬的指导。下面是大佬的博客,Android开发的小伙伴可以关注他。
主页传送门https://me.csdn.net/maosidiaoxian