在使用Java开发Android程序时,总是要写一大堆的findViewById。后来有了一些诸如ButterKnife之类的,专门用于对findViewById的用法进行简化,但是ButterKnife还是要通过注解来让控件与资源id之间进行绑定,并不算是非常方便。随着kotlin的流行,kotlin-android-extensions插件很好的解决了这个问题。或者是出于性能的考虑,这个插件也被挂上了deprecated的标签,官方推荐使用ViewBinding来进行替代。目前ViewBinding是我们舍弃findViewById的最佳解决方案,它不仅支持Kotlin同样也支持Java.
注意事项
第一,确保你的Android Studio是3.6或更高的版本。
第二,在你项目工程模块的build.gradle中加入以下配置:
android {
...
buildFeatures {
viewBinding true
}
}
如何使用
启动了ViewBinding功能后,Android Studio会自动为我们所编写的每一个布局文件都生成一个对应的Binding类。
Binding类的命名规则是将布局文件按驼峰方式重命名后,再加上Binding作为结尾。
比如说,前面我们定义了一个activity_main.xml布局,那么与它对应的Binding类就是ActivityMainBinding。
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
如果有些布局文件你不希望为它生成对应的Binding类,可以在该布局文件的根元素位置加入如下声明:
<LinearLayout
xmlns:tools="http://schemas.android.com/tools"
...
tools:viewBindingIgnore="true">
...
</LinearLayout>
如何在include和merge的布局中使用ViewBinding
include
比如我们有个bottom_layout.xml通用底部布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/rx"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="版权所有"/>
</LinearLayout>
在我们的activity_main.xml中引用
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
android:gravity="center_horizontal"
tools:context=".MainActivity">
...
<include layout="@layout/bottom_layout" android:id="@+id/page_bottom"/>
</LinearLayout>
注意,要给include里加一个id否则找不到。
此时我们就可以在MainActivity中引用到binding.pageBottom.rx.setText("R");
merge
由于merge没有根view,所以没办法设置id,所以只能设置两个binding来实现
binding = ActivityMainBinding.inflate(layoutInflater);//原binding
mergeBinding = MergeLayoutBinding.bind(binding.root);//merge进来的binding,xml名称为merge_layout.xml
setContentView(binding.root);
mergeBinding.mtextview.setText("merge1");