2017-05-31 30 views
11

我想第一次使用Kotlin構建android應用程序。用Kotlin在android中聲明UI組件的最佳方式是什麼?

我想在OnCreate方法之外的某些按鈕上聲明,我只能初始化它們在這個函數中使用findViewById。

我可以在java中聲明簡單而乾淨的代碼嗎?

private Button btnProceed; 

因爲其轉換成科特林它看起來像當:

private var btnProceed: Button? = null 

然後當初始化的OnClick功能需要添加! sign:

btnProceed!!.setOnClickListener 

什麼是正確和最乾淨的方式?

+0

的可能的複製[「lateinit」或「懶人通過」定義全局android.widget VAR時/ VAL(https://stackoverflow.com/questions/44056988/lateinit-by-lazy-when-defining-global-android-widget-var-val) –

+0

嗨Daniel,我的問題更基本。你是對的,在你的參考答案中回答我的問題,但如果有人不熟悉lateinit或懶惰(像我這樣)不會像我沒有發現這個問題。 – Udi

回答

12

這是一個很好的用例lateinit。標記屬性lateinit可讓您將其設爲非空,但在您的Activity的構造函數被調用時不會爲其賦值。在初始化發生在一個單獨的初始化方法中的時候,比運行的構造函數晚(在這種情況下,onCreate),它正是在那裏。

private lateinit var btnProceed: Button 

如果屬性是讀前的實際價值被分配給它,它會在運行時拋出一個異常 - 通過使用lateinit,你服用的責任初始化它,你訪問它首次之前。


否則,如果您希望編譯器以保證您的安全訪問,可以爲轉換器在默認情況下確實讓Button空。

btnProceed?.setOnClickListener { ... } 

這將使正常通話,如果btnProceed是一個非空值,什麼也不做,否則:取而代之的是不安全!! operator不過,該轉換器經常使用的,你應該在哪裏,你訪問屬性使用 。


關於最後一點,你可以檢查出Kotlin Android Extensions,它無需共創您View的屬性,它是否適合你的項目。


最後編輯(現在):你也應該看作爲otheranswers描述了使用lazy。懶惰很酷。

+0

非常感謝!偉大而明確的答案 – Udi

1

你可以這樣做lateinit作爲@ zsmb13建議但是這有一個缺點,你的意見將是可變的而不是最終的。如果你希望他們最終可以使用lazy property delegation

通過使用lazy你可以聲明如何,當你第一次嘗試通過聲明

private val btnProceed: Button by lazy { 
    findViewById(R.id.yourID) 
} 

訪問它。所以每當你訪問你btnProceed值將被初始化你有你自己的活動(這個例子假設你正在使用的活動)加載,以便您可以使用該方法

7

而不是使用lateinit的,你也可以做lazy initialization

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 { ... } 
} 
相關問題