2.2.3.Architecture components_View Binding
Posted muouren
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2.2.3.Architecture components_View Binding相关的知识,希望对你有一定的参考价值。
参考
https://developer.android.com/topic/libraries/view-binding
简介
简单来说就是来代替findViewById的。
配置
在AndroidStudio3.6及以上版本可用,
在模块的build.gradle中加入:
android { ... viewBinding { enabled = true } }
其他不用配置,编译时自动生成对应的绑定类。
绑定类的名字是由xml的名字生成的,比如result_profile.xml,那么生成的绑定类就是ResultProfileBinding。
使用
生成的绑定类中会有布局根view和有id的view的引用,
在Activity中使用
private ResultProfileBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ResultProfileBinding.inflate(getLayoutInflater()); View view = binding.getRoot(); setContentView(view); }
然后就可以用这个绑定对象直接访问view。
在Fragment中使用
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() { binding = null; }
不想用
在布局根view上加入tools:viewBindingIgnore="true"
<LinearLayout ... tools:viewBindingIgnore="true" > ... </LinearLayout>
和findViewById的不同
与使用findViewById相比,视图绑定具有重要的优势:
- l 空安全性:由于视图绑定会创建对view的直接引用,因此不会因无效的视图ID而导致空指针异常的风险。
此外,当view仅在布局的某些配置中存在时,在绑定类中包含其引用的字段将用@Nullable标记。
- l 类型安全性:每个绑定类中的字段具有与其在XML文件中引用的view匹配的类型。 这意味着没有类强制转换异常的风险。
这些差异意味着布局和代码之间的不兼容性将导致 build失败 在编译时 而不是 在运行时。
和DataBinding的不同
Data Binding和View Binding都会生成的绑定类,
view binding生成的绑定类直接实现ViewBinding接口,
而DataBinding生成的绑定类是继承ViewDataBinding,而ViewDataBinding实现了ViewBinding接口。
view binding只是简单的findViewById,
而Data binding除了findViewById外,还有数据绑定的功能。
include
activity_databinding.xml
<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=".MainActivity"> <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <include android:id="@+id/databinding1" layout="@layout/databinding1" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <include android:id="@+id/no_binding" layout="@layout/list_item" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@id/databinding1" /> </androidx.constraintlayout.widget.ConstraintLayout>
上边布局有两个include,databinding1是一个绑定布局,而第二个是普通布局,都加上了id。
不管是什么类型的布局,我们都可以通过activity_databinding的viewbinding对象直接访问引用的绑定对象,而不用手动获取。
databinding1就是直接访问绑定布局对象,第二个是直接访问它的viewbinding对象。
Databinding1Binding databinding1Binding = activityDataBindingBinding.databinding1;
ListItemBinding noBinding = activityDataBindingBinding.noBinding;
分析
那么看一下生成的ViewBinding类就能明白具体是怎么操作的:
@NonNull public static ActivityDatabindingBinding 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: { View databinding1 = rootView.findViewById(R.id.databinding1); if (databinding1 == null) { missingId = "databinding1"; break missingId; } Databinding1Binding databinding1Binding = Databinding1Binding.bind(databinding1); View noBinding = rootView.findViewById(R.id.no_binding); if (noBinding == null) { missingId = "noBinding"; break missingId; } ListItemBinding noBindingBinding = ListItemBinding.bind(noBinding); TextView tv = rootView.findViewById(R.id.tv); if (tv == null) { missingId = "tv"; break missingId; } return new ActivityDatabindingBinding((ConstraintLayout) rootView, databinding1Binding, noBindingBinding, tv); } throw new NullPointerException("Missing required view with ID: ".concat(missingId)); }
可以看到生成的viewbinding类自动帮我们做了获取绑定对象的步骤。
以上是关于2.2.3.Architecture components_View Binding的主要内容,如果未能解决你的问题,请参考以下文章
[Vue @Component] Simplify Vue Components with vue-class-component
[Vue @Component] Dynamic Vue.js Components with the component element