使用databinding¶
更新日期 2022-8-1
- 2022-8-1 新版本 SDK 32 用法
- 2020-4-20 创建文档
通过databinding功能,您可以更轻松地编写可与视图交互的代码。在模块中启用databinding之后,系统会为该模块中的每个 XML 布局文件生成一个绑定类。绑定类的实例包含对在相应布局中具有 ID 的所有视图的直接引用。
在大多数情况下,databinding会替代 findViewById
。当然它不只是这点作用。
启用databinding¶
在使用Android SDK 32的时候,项目gradle文件配置如下
相对于上面这里修改为使用buildFeatures
layout中不需要做什么特别处理。
旧版本¶
启用databinding,需要在模块的gradle文件中添加
在layout中,添加<layout>
标签。例如act_data_binding_1.xml
文件。
其中包含了data标签与view标签,view标签的内容就是不使用DataBinding时的普通布局内容
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:binding="http://schemas.android.com/tools">
<!-- 根视图 -->
<LinearLayout.... />
</layout>
系统会通过以下方式生成绑定类的名称:将 XML(layout)文件的名称转换为驼峰式大小写,并在末尾添加“Binding”一词。
上面的xml会生成ActDataBinding1Binding
类。我们可以直接使用这个类。
Java中调用¶
在DataBindingAct1
中,也需要调用setContentView
。
public class DataBindingAct1 extends AbsActivity {
ActDataBinding1Binding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActDataBinding1Binding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
binding.tv1.setText("现在可以直接使用layout中的TextView了");
binding.tv2.setText("可以不用findViewById");
}
}
可以看到,我们不用写那么多findViewById
了。可以直接使用binding
。
每个绑定类还包含一个getRoot()
方法,用于为相应布局文件的根视图提供直接引用。在此示例中,ActDataBinding1Binding
类中的 getRoot()
方法会返回 LinearLayout
根视图。
使用DataBindingUtil¶
前面在onCreate中使用了ActDataBinding1Binding.inflate(getLayoutInflater())
,
我们也可以换用DataBindingUtil.setContentView
。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.act_data_binding_1);
// ...
}
binding 与 findViewById 的区别¶
与使用 findViewById
相比,视图绑定具有一些很显著的优点:
- Null 安全:由于视图绑定会创建对视图的直接引用,因此不存在因视图 ID 无效而引发 Null 指针异常的风险。此外,如果视图仅出现在布局的某些配置中,则绑定类中包含其引用的字段会使用 @Nullable 标记。
- 类型安全:每个绑定类中的字段均具有与它们在 XML 文件中引用的视图相匹配的类型。这意味着不存在发生类转换异常的风险。
这些差异意味着布局和代码之间的不兼容性可能会导致编译版本在编译时(而非运行时)失败。
基础Activity示例¶
我们设计一个抽象类BaseAct
封装一些常用操作,它指定了继承自ViewDataBinding的范型。
/**
* activity 抽象类
*/
public abstract class BaseAct<B extends ViewDataBinding> extends AppCompatActivity {
protected B binding;
/**
* @return 界面对应的layout id
*/
protected abstract int getLayoutId();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, getLayoutId());
}
}
实现类继承BaseAct
,指定ViewDataBinding的子类后,直接可以使用binding对象了。
public class MainActivity extends BaseAct<ActMainBinding> {
@Override
protected int getLayoutId() {
return R.layout.act_main;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 具体操作
}
@Override
public void onBackPressed() {
}
}
📖 Observable 📖 ObservableField
本站说明
一起在知识的海洋里呛水吧。广告内容与本站无关。如果喜欢本站内容,欢迎投喂作者,谢谢支持服务器。如有疑问和建议,欢迎在下方评论~