使用ViewBinding能夠大幅減少獲取View(視圖元件)的程式碼量。其原因是你再獲取元件時不必宣告一堆變量儲存控件和不必再寫一堆findViewById()。
上面的對比圖都是實現一樣的頁面功能,雖然只有三個控件,但可以很明顯看出使用ViewBinding的好處。
在build.gradl添加這一行
android {
...
buildFeatures {
viewBinding true
}
}
按下"Sync Now"
此時項目內的UI佈局(xml檔) 都會被==自動==編譯成一個對應的ViewBinding類,而這個類實際上只是幫我們完成了findViewById()。
其中產生類明的規則是: UI佈局xml的檔名轉換為駝峰命名的格式再加上Binding。
例如:"activity_login.xml"
-> "ActivityLoginBinding"
Class
有一個這樣的UI,檔案名稱是"activity_main.xml"。
當啟用了ViewBinding功能,這個UI(xml文件)就會自動被編譯成 ActivityMainBinding類。
只要再完成以下的兩個步驟, 就可以在這個頁面使用ViewBinding了。
public class MainActivity extends AppCompatActivity {
// ⓵
ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ⓶
binding = ActivityMainBinding.inflate(getLayoutInflater());
//替代掉setContentView(R.layout.activity_main);
setContentView(binding.getRoot());
// 設置login按鈕點擊事件
binding.login.setOnClickListener(this::login);
}
// 按下登入 打印使用者輸入的帳號密碼
private void login(View v) {
Log.e("ian", binding.username.getText().toString());
Log.e("ian", binding.password.getText().toString());
}
}
❶: 宣告ViewBinding綁定類。
❷: 取得ViewBinding實例,注意這一行一定要寫再setContentView()前,然後再替換掉原本的setContentView裡的佈局Id R.layout.activity_main
為 binding.getRoot()
。
另外,如果你希望某個布局不要自動生成(ViewBinding)綁定類的話,可以在佈局的根標籤內打上這一句:
<LinearLayout
...
tools:viewBindingIgnore="true" >
...
</LinearLayout>
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding; // Step1
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater()); // Step2
// setContentView(R.layout.activity_main) 替代為底下的程式碼
setContentView(binding.getRoot()); // Step3
}
...
}
public class XxxxFragment extends Fragment {
private static XxxxCollectionBinding binding; // step1
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
// return inflater.inflate(R.layout.fragment_a, container, false); 替代為以下兩行程式碼
binding = FragmentCollectionBinding.inflate(inflater, container, false); // step2
return binding.getRoot(); // step3
}
...
}