ViewBind的使用
JetPack出來後,增加了視圖綁定的工具,方便我們不再需要手寫findViewById,節省了大量時間,應該比ButterKnife更加簡便。
接下來,將對視圖綁定的使用和原理進行分析。
開啓視圖綁定
注意:使用視圖綁定需要在Android Studio3.6(Canary 11)版本以上使用
在Module的gradle文件中開啓視圖綁定
android{
viewBinding{
enabled = true
}
}
視圖綁定的前期瞭解
在開啓視圖綁定後,我們就可以和平時一樣操作xml視圖了(添加textView 添加Button等等)。然後Android Studio會給我們的每個xml生成相應的綁定類,
比如我當前的xml名字叫做:/activity_use_view_bind.xml/,那麼,相對應的綁定類就叫:/ActivityUseViewBindBinding/。也就是在後面添加Binding。
如果不想讓工具幫忙生成相應的綁定類,可以在xml的根視圖中中添加
tools:viewBindingIgnore=“true"
視圖綁定的簡單上手
開始上手吧!
我們就在xml中簡單添加一個TextView 和 Button
然後在Activity類中
class UseViewBindActivity : AppCompatActivity() {
//聲明一個綁定類
lateinit var binding : ActivityUseViewBindBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//創建綁定類
binding = ActivityUseViewBindBinding.inflate(layoutInflater)
//設置ContentView
setContentView(binding.root)
binding.button.setOnClickListener {
binding.textView.text = “666”
}
}
}
使用靜態方法inflate創建綁定類,同時,我們可以通過getRoot方法,獲取到該xml的根視圖。把root交給setContentView,如此,視圖綁定就完成了。
在activity中,我們就可以使用binding對象獲取到xml中的控件了。
分析原理
原理其實非常簡單,只要找到系統爲我們生成的綁定類,一看代碼就知道了。
/ActivityUseViewBindBinding/類具體位置在build文件夾下
上代碼
public final class ActivityUseViewBindBinding implements ViewBinding {
@NonNull
private final ConstraintLayout rootView;
@NonNull
public final Button button;
@NonNull
public final TextView textView;
private ActivityUseViewBindBinding(@NonNull ConstraintLayout rootView, @NonNull Button button,
@NonNull TextView textView) {
this.rootView = rootView;
this.button = button;
this.textView = textView;
}
@Override
@NonNull
public ConstraintLayout getRoot() {
return rootView;
}
@NonNull
public static ActivityUseViewBindBinding inflate(@NonNull LayoutInflater inflater) {
return inflate(inflater, null, false);
}
@NonNull
public static ActivityUseViewBindBinding inflate(@NonNull LayoutInflater inflater,
@Nullable ViewGroup parent, boolean attachToParent) {
View root = inflater.inflate(R.layout.activity_use_view_bind, parent, false);
if (attachToParent) {
parent.addView(root);
}
return bind(root);
}
@NonNull
public static ActivityUseViewBindBinding bind(@NonNull View rootView) {
// The body of this method is generated in a way you would not otherwise write.
// This is done to optimize the compiled bytecode for size and performance.
String missingId;
missingId: {
Button button = rootView.findViewById(R.id.button);
if (button == null) {
missingId = "button";
break missingId;
}
TextView textView = rootView.findViewById(R.id.textView);
if (textView == null) {
missingId = “textView”;
break missingId;
}
return new ActivityUseViewBindBinding((ConstraintLayout) rootView, button, textView);
}
throw new NullPointerException("Missing required view with ID: ".concat(missingId));
}
}
調用inflate方法來生成一個綁定類,在inflate方法中,會先去創建我們的根視圖(root),看到沒,這裏已經保存了對應的xml文件。是不是和手動創建xml的view一樣?
然後調用bind方法,在根視圖(root)中,還是調用了findViewById方法嘛,不過,幫我們多做了一些事,判斷view是不是空的。
最後,如果視圖都創建成功了,就直接返回該綁定類對象,我們在代碼中也就可以直接使用了哈。
拓展思考:
ButterKnife可能是大家用的最多的庫,用來代替findViewById。而ButterKnife是通過APT技術(Annotation Processing Tool)來生成一個綁定工具類,在編譯的時候,記錄下@BindView的控件。在運行時,直接幫助這些控件findViewById,爲每個控件動態綁定。
總結
- 視圖綁定自動幫我們進行的空判斷,所以就不怕在視圖引用的過程中發生空安全。
- 在綁定類中,我們看到,xml中是什麼控件,他就是什麼控件,也避免了我們findViewById時,強轉發生的錯誤。