是时候拥抱ViewBinding了!!
沉舟侧畔千帆过,
病树前头万木春。
– 唐·刘禹锡
一、前言
随着Android Studio 3.6的正式发布,我义无反顾的走在了更新尝鲜的前列。AS的升级一如往常的顺利,重启后就进入了令人血脉喷张的 Gradle 升级的环节,需要从3.5.1升级到3.6.0。果不其然,出问题了!!
ButterKnife居然报错,日志如下:
D:\xxx\libbase\component\dialog\BottomDialog.java:33: : Attempt to use @BindView for an already bound ID 0 on 'mTvNegative'. (com.xxx.libbase.component.dialog.BottomDialog.mLayoutContent)
ViewGroup mLayoutContent;
我真是摸不着头脑啊。解决吧,升级ButterKnife、翻资料、找issue、看源码等等等等。最终老天不负有心人,我将Gradle版本回退了,一切都回归平静。【如果有解决办法的请告知我,感激不尽】
二、初识ViewBinding
它和ButterKnife一样都是为了省去findViewById()这样的重复代码。其实在2019谷歌开发者峰会上对ViewBinding就已经有所耳闻了,layout中更新控件ID后立刻可以在Activity中引用到,这绝对比ButterKnife需要编译、需要区分R和R2要舒服的多。
上面升级到3.6.0就是为了使用它,然而现实永远这么的残酷,十之八九不尽人意,ViewBinding和ButterKnife看来只能二选一了。
三、拥抱ViewBinding
关于ViewBinding的文档,官方写的很详细,请看 视图绑定 。本文一切从简,主要说下Google官方没有提到的一些问题。
3.1、环境要求
- Android Studio版本3.6及以上
- Gradle 插件版本3.6.0及以上
3.2、开启ViewBinding功能
ViewBinding支持按模块启用,在模块的build.gradle文件中添加如下代码:
android {
...
viewBinding {
enabled = true
}
}
3.3、Activity中ViewBinding的使用
//之前设置视图的方法
setContentView(R.layout.activity_main);
//使用ViewBinding后的方法
mBinding = ActivityMainBinding.inflate(LayoutInflater.from(this));
setContentView(mBinding.getRoot());
可以看到,当你使用了ViewBinding后,针对你的activity_main.xml文件,会自动帮你生成一个ActivityMainBinding.java文件(该文件在build/generated/data_binding_base_class_source_out/xxx…目录下),也就是布局文件的驼峰命名法加上一个Binding后缀,然后在Activity中直接使用就可以。
3.3.1、布局中直接的控件
当我们在布局中添加一个id为 tv_text 的TextView后,直接在Activity中使用mBinding.tvText即可拿到该控件。如下所示,可以看到也是以控件ID的驼峰命名法来获取的:
mBinding.tvText.setText("是你得不到的ViewBinding");
3.3.2、布局中导入的控件
例如我们有个layout_comment.xml的布局,布局中有id为tv_include的TextView,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_include"
android:text="这就是测试啊"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
然后在activity_main.xml文件中include该布局:
<?xml version="1.0" encoding="utf-8"?>
<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_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<include
android:id="@+id/layout_include"
layout="@layout/layout_comment" />
</androidx.constraintlayout.widget.ConstraintLayout>
那么此时我们如何使用到layout_comment.xml布局中的TextView控件呢,首先include标签需要声明id,例如layout_include,然后Activity中代码如下:
mBinding.layoutInclude.tvInclude.setText("这就是你的不对了");
是不是很神奇,是不是很简单。
注意:
当你给layout_comment.xml的根布局再添加id(比如添加了layout_xxx的ID)的时候,此时会报错:
java.lang.NullPointerException: Missing required view with ID: layout_xxx
乐翁龙
发布了40 篇原创文章 · 获赞 47 · 访问量 7万+
私信
关注