Android 使用View Binding的方法详解
前言
Android Studio稳定版发布了3.6版本,带来了一些新变化:首先外观,启动页变了,logo改了,更显现代化;增加Multi Preview功能,能同时预览多个尺寸屏幕的显示效果;模拟器支持多屏;也终于支持全新的视图绑定组件View Binding;等。
之前我们与视图交互的方式有findViewById、kotlin中引入Android Kotlin Extensions后直接通过id进行访问。前者模板化严重,重复代码多;后者最为方便。现在有了新的选择–View Binding,官方解释:
通过视图绑定功能,您可以更轻松地编写可与视图交互的代码。在模块中启用视图绑定之后,系统会为该模块中的每个 XML 布局文件生成一个绑定类。绑定类的实例包含对在相应布局中具有 ID 的所有视图的直接引用。
在大多数情况下,视图绑定会替代 findViewById。
使用
View Binding可按模块启用。要在某个模块中启用,在该模块的build.gradle中添加如下配置:
android {
...
viewBinding {
enabled = true
}
}
用法
当某个模块启用View Binding后,系统会为该模块中包含的每个 XML 布局文件各生成一个绑定类。每个绑定类均包含对根视图以及具有id 的所有视图的引用。绑定类的类名是xml的名称后面加“Binding”。
例如,假设某个布局文件名为 比如activity_main.xml:
<LinearLayout ...
<TextView android:id="@+id/tvName" /
<TextView android:text="no id"/
<Button android:id="@+id/btnOpen"/
</LinearLayout
那么生成的绑定类类名是ActivityMainBinding。这个类有两个成员变量tvName和btnOpen,还包含一个getRoot()方法,返回根视图,此例中返回LinearLayout。
要获取绑定类的实例,可以通过静态 inflate() 方法。
private lateinit var binding: ActivityMainBinding
@Override
fun onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(inflater)
setContentView(binding.root)
}
现在,绑定类的实例可用于引用任何视图:
binding.tvName = "name"
binding.btnOpen.setOnClickListener{
Log.d(TAG,"btnOpen click")
}
区别
- 与findViewById的区别:空安全和类型安全,不存在因引用了一个错误的id而导致的空指针异常或者类型转换异常。
- 与databinding的区别:databinding仅处理使用 <layout 代码创建的数据绑定布局;View Binding不支持布局变量或布局表达式,因此它不能用于在xml中将布局与数据绑定。
- 与Android Kotlin Extensions的区别:在使用上,后者简单粗暴,直接id进行访问,而View Binding需要创建绑定类的实例;后者有一些不友好的地方,比如相同的id存在于多个xml,容易导错包,如果包导错了,会有可能别的View用错id导致空指针,而View Binding显然不会有这种情况。
总结
如果与findViewById或者其他View注入框架进行选择,建议选择View Binding,代码更为简洁和安全。
如果是使用databinding的项目,可以使用View Binding作为补充,用来处理非<layout 为根标签的xml。(ps:貌似不可能出现这种场景?也应该避免这种场景,毕竟类生成过多会影响build速度和增加安装包体积)
与Android Kotlin Extensions进行选择,目前来看,无最优解,二者都很好,取决于开发者是想开发效率最大化、代码简洁使用方便(Android Kotlin Extensions)还是倾向于稳健、出错几率最小化(View Binding)。
By the way,View Binding目前还不支持include标签引入的xml。View Binding功能的完善、在未来的地位和作用、以及能否超越Android Kotlin Extensions,我们仍需持续关注其后续版本。
到此这篇关于Android 使用View Binding的方法详解的文章就介绍到这了。
- 教您最简单粗暴的MATLAB入门级爬虫2
- 前台JS(Jquery)调用后台方法 无刷新级联菜单示例
- 项目中对图片的缩放和水印效果
- 照虎画猫写自己的Spring——自定义注解
- 数据分析进阶课程笔记(六)
- 微信发布重磅更新!上线小游戏,小程序间可快速切换
- 鼠标点击层以外的地方层隐藏
- WCF后续之旅(11): 关于并发、回调的线程关联性(Thread Affinity)
- WCF后续之旅(11): 关于并发、回调的线程关联性(Thread Affinity)
- 解决文本框在updatepanel中得到焦点,输入法不能切换到中文的问题
- 得到真实外网IP、IP所在国家、省份、地区
- 机器学习在智能制造中的应用!
- sql2008 附加数据库时 错误5123
- Logistic Regression Models分析交互式问答译
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 3大利器推荐,帮你写出规范漂亮的python代码
- 【Docker】修改docker镜像存储的路径
- conda报错
- docker安装和使用
- JAVA-常量及常量池
- 解决哈希冲突的常用方法分析
- 03 Confluent_Kafka权威指南 第三章: Kafka 生产者:向kafka写消息
- kafka生产者和消费者的基本操作
- 05 Confluent_Kafka权威指南 第五章: kafka内部实现原理
- 关于leetcode第718题求长度最长的公共子数组的解析
- JAVA类加载过程&主动引用和被动引用
- 关于leetcode第56题合并重复区间的解析
- java-覆盖equals和hashcode方法
- java-单链表反转解法及分析
- JAVA-判断两个单链表是否相交并求交点