AndroidStudio视图绑定简记
视图绑定(暂适用于AndroidStudio 3.6-4.1)
(2020.11.10)
Android Studio 3.6加入了视图绑定,能够为每个xml布局文件自动生成绑定类。这些类包含对在相应布局中具有 ID 的所有视图的直接引用。大多数情况下,可以取代findViewById()
。
如需启用视图绑定,需要使用 Android Gradle 插件 3.6.0 或更高版本。
启用说明
如果要在某个模块中启用视图绑定,需要将viewBinding元素添加到app目录下的build.gradle文件中:
android{
...
viewBinding{
enabled = true
}
}
如果希望在生成绑定类的时候不需要绑定某个布局文件,则需要添加以下属性到相应布局文件的根视图中,tools:viewBindingIgnore="true"
<LinearLayout
...
tools:viewBindingIgnore="true" >
...
</LinearLayout>
用法
启用视图绑定后,系统会为该模块中的每个xml布局文件自动生成一个绑定类,这个类位于
目录下。
每个类的属性或方法和布局文件中每一个具有ID的视图形成一种映射关系,可以对这些视图进行引用。
命名规则:将 XML 文件的名称转换为驼峰式大小写,并在末尾添加“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
根视图。
在Activity中使用视图绑定
在使用findViewById()的时候加载布局是这样:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.id.layout.activity_main);
}
而使用视图绑定的时候需要改成这样:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//使用视图绑定
//创建绑定类的实例
activityMainBinding = ActivityMainBinding.inflate(getLayoutInflater());
//获取根视图的引用
View view = activityMainBinding.getRoot();
setContentView(view);
}
步骤如下:
- 调用生成的绑定类中包含的静态
inflate()
方法。此操作会创建该绑定类的实例以供 Activity 使用。 - 通过调用
getRoot()
方法或使用 Kotlin 属性语法获取对根视图的引用。 - 将根视图传递到
setContentView()
,使其成为屏幕上的活动视图。
接下来就可以引用任何具有ID的视图:
activityMainBinding.button.setOnClickListener(new View.OnClickListener() {
viewModel.userClicked()});
在Fragment中使用视图绑定
和在Activity中类似,在Fragment的onCreateView()
方法中进行修改,步骤如下:
- 调用生成的绑定类中包含的静态
inflate()
方法。此操作会创建该绑定类的实例以供 Fragment 使用。 - 通过调用
getRoot()
方法或使用 Kotlin 属性语法获取对根视图的引用。 - 从
onCreateView()
方法返回根视图,使其成为屏幕上的活动视图。
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;
}
引用:
binding.button.setOnClickListener(new View.OnClickListener() {
viewModel.userClicked()
});
注意:
Fragment存在时间比其视图长,所以务必在Fragment的
onDestroyView()
方法中清除对绑定类实例的所有引用。
与findViewById的区别
与使用 findViewById
相比,视图绑定具有一些很显著的优点:
- Null 安全:由于视图绑定会创建对视图的直接引用,因此不存在因视图 ID 无效而引发 Null 指针异常的风险。此外,如果视图仅出现在布局的某些配置中,则绑定类中包含其引用的字段会使用
@Nullable
标记。 - 类型安全:每个绑定类中的字段均具有与它们在 XML 文件中引用的视图相匹配的类型。这意味着不存在发生类转换异常的风险。
这些差异意味着布局和代码之间的不兼容将会导致构建在编译时(而非运行时)失败。