Android&Kotlin筆記1——TextView賦值出現java.lang.IllegalStateException: tv must not be null
阿新 • • 發佈:2019-01-10
前言
現在有很多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<TextView>(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<TextView>(R.id.tv) btn.setOnClickListener { DatePickerDialog(this).run { show() setOnDateSetListener { datePicker, _, _, _ -> time.text = datePicker.year.toString() + (datePicker.month + 1) + datePicker.dayOfMonth } } } }
我初始化的元件之後,我在dialog裡面找到這個元件,然後在activity中賦值成功。成功解決了上面說的問題,很感謝大佬的指導。下面是大佬的部落格,Android開發的小夥伴可以關注他。