View Binding 是什麼 ?
View Binding 是一個機制,可以讓開發者更簡單以及更安全的參考佈局檔的 UI 元件。
ref : https://developer.android.com/topic/libraries/view-binding
當 Module 啟動 View Binding 之後,該 Module 內每個佈局檔都會產生一個相對應的 binding class,binding class 會包含其對應的佈局檔中具有 id 的屬性,使用者便可透過 binding class 直接操作佈局檔的 UI 元件,不必再寫 findViewById。
View Binding 用來做什麼 ?
在大部分的情況下,View Binding 用來取代 findViewById。
設定和相依性
注意
1.目前(2019-09-12)只支援 Android Studio 3.6 Canary 11+
2.如果已經使用 data binding,不必再啟動 View Binding
在 Module 的 build.gradle 啟動 View Binding
android {
...
viewBinding {
enabled = true
}
}
如果不想為某個佈局檔自動產生 binding class,在該佈局檔中加入以下設定
<LinearLayout
...
tools:viewBindingIgnore="true" >
...
</LinearLayout>
用法
在 Module 中啟動 View Binding 之後,只要執行 make project,便會為該 Module 中每個佈局檔建立 binding class。
binding class 檔案位於
app -> build -> generated -> data_binding_base_class_source_out -> debug -> out -> package name -> databinding
(這個其實不重要,因為不必手動修改它)
binding class 名稱會根據對應的佈局檔延伸,規則是佈局檔+Binding
假設有一個為 activity_view_binding_example.xml 佈局檔,內容如下。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ViewBindingExampleActivity">
<TextView
android:id="@+id/view_binding_example_hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/view_binding_example_click_me"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="click me"
app:layout_constraintLeft_toLeftOf="@+id/view_binding_example_hello_world"
app:layout_constraintTop_toBottomOf="@+id/view_binding_example_hello_world" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="bottom button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
可以看到其中一個 TextView 和 Button 都有 id,而另一個 Button 沒有 id。
binding class 會自動持有具有 id 屬性的 UI 元件變數,忽略掉沒有 id 屬性的UI 元件。
對應的 binding class 名稱為 ActivityViewBindingExampleBinding。它會持有名為 viewBindingExampleClickMe 變數以及 viewBindingExampleHelloWorld 變數。這兩個變數對應佈局檔的
<TextView
android:id="@+id/view_binding_example_hello_world"
...
/>
<Button
android:id="@+id/view_binding_example_click_me"
...
/>
只要將 ViewBinding 初始化之後就可以透過這兩個變數來操作佈局檔的 UI 元件,以下為在 Activity 中使用的範例。
class ViewBindingExampleActivity : AppCompatActivity() {
private lateinit var mViewBinding: ActivityViewBindingExampleBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mViewBinding = ActivityViewBindingExampleBinding.inflate(layoutInflater)
setContentView(mViewBinding.root)
initUI()
}
private fun initUI() {
mViewBinding.viewBindingExampleClickMe.setOnClickListener { _ ->
Toast.makeText(this, "change to NEW hello world!!!", Toast.LENGTH_SHORT).show()
mViewBinding.viewBindingExampleHelloWorld.text = "new hello world"
}
}
}
mViewBinding 就是 binding class 的實體變數。
注意初始化 mViewBinding 的呼叫順序部分。初始化完 mViewBinding 之後呼叫setContentView 方法是傳入 mViewBinding 的 root 方法回傳值。
root 方法其實就是回傳對應佈局檔的根元素,本範例就是 ConstraintLayout。
mViewBinding = ActivityViewBindingExampleBinding.inflate(layoutInflater)
setContentView(mViewBinding.root)
而在 initUI 方法中就是透過 mViewBinding 操作 UI 元件,不須經過初始化也不用 findViewById。
private fun initUI() {
mViewBinding.viewBindingExampleClickMe.setOnClickListener { _ ->
Toast.makeText(this, "change to NEW hello world!!!", Toast.LENGTH_SHORT).show()
mViewBinding.viewBindingExampleHelloWorld.text = "new hello world"
}
}
優勢
View Binding 透過提供 binding class 的實體來操作 UI 元件,這種方式比 findViewById 多了一些好處(就是不用寫 findViewById!!)。
首先為型態安全,因為不必在意呼叫 findViewById 時轉型的型態是否正確。
第二為 Null 安全,因為不必在意呼叫 findViewById 時指定 UI 元件的 ID。
和 Data Binding 的不同
- Data Binding 只處理使用<layout>標籤來綁定數據。
- View Binding 無法處理在佈局檔定義的變數以及表達式。
總結
就目前而言 View Binding 是很簡易的新特性,用途有限,主要用於取代 findViewById,其 binding class 提供的方法也不多。