檢視繫結 Android Jetpack 的一部分。
檢視區塊繫結功能可讓您輕鬆編寫與檢視區塊互動的程式碼。在模組中啟用檢視繫結後,便會為該模組中的每個 XML 版面配置檔案產生繫結類別。凡是在對應版面配置中具有 ID 的檢視區塊,繫結類別的例項都會包含指向這些檢視區塊的直接參照。
在大多數情況下,檢視繫結會取代 findViewById
。
設定
每個模組都會啟用檢視繫結。如要啟用模組中的檢視區塊繫結,請在模組層級 build.gradle
檔案中將 viewBinding
建構選項設為 true
,如以下範例所示:
Groovy
android { ... buildFeatures { viewBinding true } }
Kotlin
android { ... buildFeatures { viewBinding = true } }
如果您想在產生繫結類別時忽略版面配置檔案,請將 tools:viewBindingIgnore="true"
屬性新增至該版面配置檔案的根層級檢視畫面:
<LinearLayout
...
tools:viewBindingIgnore="true" >
...
</LinearLayout>
使用方法
如果模組已啟用檢視區塊繫結,則系統會為模組包含的每個 XML 版面配置檔案產生繫結類別。每個繫結類別都包含根檢視畫面和具有 ID 的所有檢視畫面的參照。系統會產生繫結類別的名稱,方法是將 XML 檔案名稱轉換為 Pascal 大小寫,並在結尾加上字詞「Binding」。
舉例來說,假設版面配置檔案名為 result_profile.xml
,其中包含以下內容:
<LinearLayout ... >
<TextView android:id="@+id/name" />
<ImageView android:cropToPadding="true" />
<Button android:id="@+id/button"
android:background="@drawable/rounded_button" />
</LinearLayout>
產生的繫結類別稱為 ResultProfileBinding
。此類別有兩個欄位:名為 name
的 TextView
,以及名為 button
的 Button
。版面配置中的 ImageView
沒有 ID,因此繫結類別中沒有任何參照。
每個繫結類別也都包含 getRoot()
方法,可針對對應版面配置檔案的根檢視畫面提供直接參照。在這個範例中,ResultProfileBinding
類別中的 getRoot()
方法會傳回 LinearLayout
根層級檢視畫面。
以下各節示範如何在活動和片段中使用產生的繫結類別。
在活動中使用檢視繫結
如要設定與活動搭配使用的繫結類別執行個體,請在活動的 onCreate()
方法中執行下列步驟:
- 在產生的繫結類別中呼叫靜態
inflate()
方法。這項操作會為活動建立繫結類別的執行個體。 - 透過呼叫
getRoot()
方法或使用 Kotlin 屬性語法取得根檢視畫面的參照。 - 將根層級檢視畫面傳遞至
setContentView()
,讓該檢視畫面在畫面上顯示的有效檢視畫面。
步驟請參見下列範例..
Kotlin
private lateinit var binding: ResultProfileBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ResultProfileBinding.inflate(layoutInflater) val view = binding.root setContentView(view) }
Java
private ResultProfileBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ResultProfileBinding.inflate(getLayoutInflater()); View view = binding.getRoot(); setContentView(view); }
您現在可以使用繫結類別的執行個體參照任何檢視畫面:
Kotlin
binding.name.text = viewModel.name binding.button.setOnClickListener { viewModel.userClicked() }
Java
binding.name.setText(viewModel.getName()); binding.button.setOnClickListener(new View.OnClickListener() { viewModel.userClicked() });
在片段中使用檢視繫結
如要設定與片段搭配使用的繫結類別執行個體,請在片段的 onCreateView()
方法中執行下列步驟:
- 在產生的繫結類別中呼叫靜態
inflate()
方法。這項操作會為要使用的片段建立繫結類別的執行個體。 - 透過呼叫
getRoot()
方法或使用 Kotlin 屬性語法取得根檢視畫面的參照。 - 透過
onCreateView()
方法傳回根層級檢視畫面,使其成為螢幕上的主動檢視畫面。
Kotlin
private var _binding: ResultProfileBinding? = null // This property is only valid between onCreateView and // onDestroyView. private val binding get() = _binding!! override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { _binding = ResultProfileBinding.inflate(inflater, container, false) val view = binding.root return view } override fun onDestroyView() { super.onDestroyView() _binding = null }
Java
private ResultProfileBinding binding; @Override public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { binding = ResultProfileBinding.inflate(inflater, container, false); View view = binding.getRoot(); return view; } @Override public void onDestroyView() { super.onDestroyView(); binding = null; }
您現在可以使用繫結類別的執行個體參照任何檢視畫面:
Kotlin
binding.name.text = viewModel.name binding.button.setOnClickListener { viewModel.userClicked() }
Java
binding.name.setText(viewModel.getName()); binding.button.setOnClickListener(new View.OnClickListener() { viewModel.userClicked() });
為不同的設定提供提示
為多項設定宣告檢視畫面時,有時建議您根據特定版面配置使用不同的檢視畫面類型。請參考以下程式碼片段範例:
# in res/layout/example.xml
<TextView android:id="@+id/user_bio" />
# in res/layout-land/example.xml
<EditText android:id="@+id/user_bio" />
在這種情況下,由於 TextView
是通用的基礎類別,您可能會預期產生的類別公開 TextView
類型的欄位 userBio
。由於技術限制,檢視區塊繫結程式碼產生器無法判斷這項資訊,並改為產生 View
欄位。這樣之後才能使用 binding.userBio as TextView
投放欄位。
如要解決這項限制,檢視區塊繫結支援 tools:viewBindingType
屬性,讓您告知編譯器要在產生的程式碼中使用哪種類型。在上述範例中,您可以使用這項屬性讓編譯器產生 TextView
欄位:
# in res/layout/example.xml (unchanged)
<TextView android:id="@+id/user_bio" />
# in res/layout-land/example.xml
<EditText android:id="@+id/user_bio" tools:viewBindingType="TextView" />
在另一個範例中,假設您有兩個版面配置,一個包含 BottomNavigationView
,另一個則包含 NavigationRailView
。這兩個類別都會擴充 NavigationBarView
,其中包含大部分的實作詳細資料。如果程式碼不需要確切知道目前的版面配置中包含哪個子類別,您可以使用 tools:viewBindingType
在這兩個版面配置中,將產生的類型設為 NavigationBarView
:
# in res/layout/navigation_example.xml
<BottomNavigationView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" />
# in res/layout-w720/navigation_example.xml
<NavigationRailView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" />
產生程式碼時,檢視區塊繫結無法驗證這個屬性的值。為了避免編譯時間和執行階段錯誤,該值必須符合下列條件:
- 值必須是繼承自
android.view.View
的類別。 這個值必須是放置標記的父類別,例如,下列值並沒有作用:
<TextView tools:viewBindingType="ImageView" /> <!-- ImageView is not related to TextView. --> <TextView tools:viewBindingType="Button" /> <!-- Button is not a superclass of TextView. -->
最終類型必須在所有設定中保持一致。
與 findViewById 的差異
相較於使用 findViewById
,檢視區塊繫結具有重要優勢:
- 空值安全:由於檢視區塊繫結會建立直接對檢視區塊的參照,因此不會因無效的檢視區塊 ID 而產生空值指標例外狀況。此外,如果檢視畫面只有版面配置的部分設定,則繫結類別中含有其參照的欄位會標示
@Nullable
。 - 類型安全:每個繫結類別中的欄位都有符合 XML 檔案所參照檢視畫面的類型。因此不會有類別轉換例外狀況的風險。
這些差異代表版面配置與程式碼之間不相容,會導致建構在編譯時間失敗,而不是在執行階段失敗。
與資料繫結比較
檢視繫結和資料繫結都會產生可讓您直接參照檢視區塊的繫結類別。不過,檢視區塊繫結用於處理較簡單的用途,並針對資料繫結提供以下優點:
- 加快編譯:檢視繫結不需處理註解,因此編譯時間會更快。
- 易於使用:檢視區塊繫結不需要特別標記的 XML 版面配置檔案,因此可更快在應用程式中採用。在模組中啟用檢視繫結後,就會自動套用至該模組的所有版面配置。
另一方面,檢視繫結對資料繫結具有以下限制:
- 檢視區塊繫結不支援版面配置變數或版面配置運算式,因此無法用來直接從 XML 版面配置檔案中宣告動態 UI 內容。
- 檢視區塊繫結不支援雙向資料繫結。
基於上述考量,在某些情況下,最好在專案中同時使用檢視繫結和資料繫結。您可以在需要進階功能的版面配置中使用資料繫結,並在未具備檢視畫面繫結的版面配置中使用檢視繫結。
其他資源
如要進一步瞭解檢視區塊繫結,請參閱下列其他資源:
範例
網誌
影片
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- 從 Kotlin 合成項目遷移至 Jetpack 檢視區塊繫結
- 版面配置與繫結的運算式
- 應用程式架構:UI 層 - 入門指南 - Android 開發人員