Viewbinding

1.环境需求

环境上,需要Android Studio 3.6 Canary 11+

同样的Gradle也需要升级(这年头都4.0了,应该没有还在用低版本的了吧...)

2.配置viewbinding

gradle 版本在 3.6 - 3.9 以上的:

app文件夹 下的 build.grale 里面添加

android {
...
viewBinding {
enabled = true
}
}

如果你的 gradle 是 4.0+ ,那么需要改一下写法

android {
...
buildFeatures {
viewBinding true
}
}

否则可能会报一个warnning,虽然不改并大概率不影响使用,但作为一个优秀程序员凑合了事可不是什么好习惯

DSL element 'android.viewBinding.enabled' is obsolete and has been replaced with 'android.buildFeatures.viewBinding'.

3.用法

原理

Viewbinding 的原理就是根据 idbuild 文件夹下生成对应的 java类,然后在 java类 里面自动帮你 findViewById(对,没错,原理还是findViewById,并没什么新鲜的),布局文件里面的子控件,就对应 java类 里面的 field(成员变量)

然后你就可以调用 java 类来操作控件

对应生成的java类文件,名字就是 删除下划线 再加 Binding

例如:activity_main.xml ==> ActivityMainBinding.java

某些布局不用viewbinding

如果你不希望某个布局(layout)被 Viewbinding 所“控制”(生成java类文件),那就添加 tools:viewBindingIgnore="true"

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:viewBindingIgnore="true">
... </LinearLayout>

Tip:可能这里你有一个骚操作——我布局采用 Viewbinding 但,某个控件不用,我自己 findViewById ,想法不错,但是Google不同意,在子布局或控件里加 tools:viewBindingIgnore="true" 是无效的

实战

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> </LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private ActivityMainBinding mMainBinding;

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mMainBinding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(mMainBinding.getRoot());
}
}

这个代码用法非常简单,就是声明一个Viewbinding帮我们生成的ActivityMainBinding,然后用inflate加载他,getRoot就是获得他的根布局,跟R.layout.activity_main是一个东西。

inflate我多说两句

inflate 跟Layoutinflate的inflate不是一个方法,但用法类似。

作用就是加载布局(初始化ViewBinding)

源码是

  @NonNull
public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater) {
return inflate(inflater, null, false);
} @NonNull
public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater, @Nullable ViewGroup parent, boolean attachToParent) {
View root = inflater.inflate(R.layout.activity_main, parent, false);
if (attachToParent) {
parent.addView(root);
}
return bind(root);
}

一共两个重载,还是很好理解的,用过LayoutInflate的肯定一看就明白

  1. 如果parent为null,attachToParent将失去作用,设置任何值都没有意义。

  2. 如果parent不为null,attachToParent设为true,则会给加载的布局文件的指定一个父布局,即parent。

  3. 如果parent不为null,attachToParent设为false,则会将布局文件最外层的所有layout属性进行设置,当该view被添加到父view当中时,这些layout属性会自动生效。

  4. 在不设置attachToParent参数的情况下,如果parent不为null,attachToParent参数默认为true。

加载控件(套娃模式)

我们先在 activity_main.xml 添加一个textView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"> ** <TextView**
** android:id="@+id/text"**
** android:layout_width="wrap_content"**
** android:layout_height="wrap_content"**
** android:background="#FF8686"**
** android:text="111"**
** android:textSize="40sp" />** </LinearLayout>

再在 MainActivity 里面编写调用代码

public class MainActivity extends AppCompatActivity {

    private ActivityMainBinding mMainBinding;

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mMainBinding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(mMainBinding.getRoot()); **mMainBinding.text.setText("dududududu");**
}
}

调用很简单,直接 mMainBinding.text.settext就可以了,这跟我们之前说的将控件 生成为java类 的成员变量也十分符合。

可我为什么称它为套娃模式呢???我们再尝试添加一个 嵌套一个layout试试

新建一个布局叫:layout_include.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"> <TextView
android:id="@+id/include_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="50sp" /> </FrameLayout>

再修改 activity_main.xml 的内容,将layout_include加载进去

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
...> <TextView
... /> **<include **
**android:id="@+id/include"**
**layout="@layout/layout_include" />**
</LinearLayout>

那么我们怎么调用 layout_include.xml 里面的 textview 呢???

我们修改MainActivity里面的代码

public class MainActivity extends AppCompatActivity {

    private ActivityMainBinding mMainBinding;
private LayoutIncludeBinding mIncludeBinding; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mMainBinding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(mMainBinding.getRoot()); mMainBinding.text.setText("dududududu"); mMainBinding.include.includeText.setText("qqqqqqqqqqq"); }
}

这就是套娃模式(当然名字是我起的)

mMainBinding.include.includeText.setText("qqqqqqqqqqq");

在布局嵌套多的时候,层层调用。

这也很好理解, mMainBinding.include 这返回的是layout_include

mMainBinding.include.includeText.setText("qqqqqqqqqqq");

这行就是 layout_include 调用自己的includeText。

别以为到这你就全会了,万一有一个布局用了 merge 怎么办???

用到merge

merge是一个解决父布局多余嵌套的一个标签,他不会最终加载到布局里,更多的是作为一个标志存在

**比如我们修改 layout_include.xml **

<?xml version="1.0" encoding="utf-8"?>
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"> <TextView
android:id="@+id/include_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="50sp" /> </merge>

这时候你再运行肯定就报错了,那是因为,merge并不会加载到布局里,而我们又给 include 添加了id,所以Viewbinding在生成 java类 的时候,随着id找过来,发现是merge,无从下手,就奔溃了。

怎么解决这个问题呢??

将include的id去掉不就行了, ^O^

你这会儿肯定又不乐意了,去掉怎么调用 include_text 呢???

细心的小可爱肯定发现了上面的inflate的源码,第一个重载调用第二个重载,第二个返回 bind(root) 。

bind 就是我们需要用到的方法了。

public class MainActivity extends AppCompatActivity {

    private ActivityMainBinding mMainBinding;
private LayoutIncludeBinding mIncludeBinding; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mMainBinding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(mMainBinding.getRoot());
... mIncludeBinding = LayoutIncludeBinding.bind(mMainBinding.getRoot());
mIncludeBinding.includeText.setText("lalala");
}
}

我们先声明了一个 LayoutIncludeBinding ,然后调用 LayoutIncludeBinding.bind(mMainBinding.getRoot()) 将其初始化,也就是将他绑定到 mMainBinding.getRoot() 上,也就是他的父布局。

这时候我们再调用 mIncludeBinding.includeText.setText("lalala"); 就没问题了

到此,关于ViewBinding基本都已经学完了,其他使用上的一些技巧就交给大家去探索了!

学学Viewbinding的更多相关文章

  1. 程序员你该学学如何设计PPT了,设计PPT的几大原则

    写代码也要读书,爱全栈,更爱生活.每日更新原创IT编程技术及日常实用视频. 我们的目标是:玩得转服务器Web开发,搞得懂移动端,电脑客户端更是不在话下. 大量的汇报及介绍工作,都离不开一个辅助工具-P ...

  2. hunnu---11547 你的组合数学学得如何?

    解析:比较简单的DP,从左向右一个一个连续着放,dp[X][Y]表示到第X个硬币的时候Y状态的方案数,Y=0表示x左边那个不是正面的,Y=1表示x左边那个是正面 如果左边不是正面,那么当前放正面的就把 ...

  3. GitHub这么火,程序员你不学学吗? 超简单入门教程 【转载】

    本GitHub教程旨在能够帮助大家快速入门学习使用GitHub. 本文章由做全栈攻城狮-写代码也要读书,爱全栈,更爱生活.原创.如有转载,请注明出处. GitHub是什么? GitHub首先是个分布式 ...

  4. 来吧学学.Net Core之项目文件简介及配置文件与IOC的使用

    序言 在当前编程语言蓬勃发展与竞争的时期,对于我们.net从业者来说,.Net Core是风头正紧,势不可挡的.芸芸口水之中,不学习使用Core,你的圈内处境或许会渐渐的被边缘化.所以我们还是抽出一点 ...

  5. 《老梁四大名著情商课》笔记-学学TA,你就是聚会的万人迷

    <老梁四大名著情商课>笔记-学学TA,你就是聚会的万人迷 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 现在社会学家有一个统计,说中国处在单身状态大概有2个亿.这些人中 ...

  6. 也来学学插件式开发续-利用MEF

    前面一个博客:也来学学插件式开发中很多朋友留言说可以用MEF来实现.于是我就试着用MEF实现了一下. 步骤和上一篇差不多,只是加载插件的方式有所不同.这只是一个自己的示例程序,肯定有很多不足之处,欢迎 ...

  7. hunnu--11547--你的组合数学学得怎样?

    你的组合数学学得怎样?  Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit users: ...

  8. SVG 学学就会了。

    SVG 随便学学就会了 这两天闲来没事把 Echart 换成 Rechart 感觉世界都清爽了.因为 rechart 使用 svg 来渲染,所以顺带学了下 SVG 感觉很轻松哦. 概念 SVG 是 w ...

  9. 最后一面挂在volatile关键字上,面试官:重新学学Java吧!

    最后一面挂在volatile关键字上,面试官:重新学学Java吧! 为什么会有volatile关键字? volatile: 易变的; 无定性的; 无常性的; 可能急剧波动的; 不稳定的; 易恶化的; ...

随机推荐

  1. 云小课 | “VPC连接”知多少

    摘要:华为云提供了丰富的网络服务,可满足多种网络互连场景. 同Region的两个VPC怎么连通?” “跨Region的两个VPC又怎么连通?” “VPC内的ECS搭建了一个应用,需要访问Interne ...

  2. Scala 基础(一):各平台安装

    一.win7环境安装1.安装jdk直接双击,安装到想要的环境目录2.修改环境变量2.1新建系统变量 JAVA_HOME 输入jdk安装目录 2.2 修改PATH修改PATH:%JAVA_HOME%\b ...

  3. 目录(Python基础)

    Python之介绍.基本语法.流程控制 Python之列表.字典.集合 Python之函数.递归.内置函数 Python之迭代器.装饰器.软件开发规范 Python之常用模块学习(一) Python之 ...

  4. 在Access中执行SQL

    1.基本介绍 Microsoft Access在很多地方得到广泛使用,例如小型企业,大公司的部门.喜爱编程的开发人员亦利用它来制作处理数据的桌面系统.它也常被用来开发简单的WEB应用程序. 2.Ace ...

  5. GEDIT外部工具

    首先通过编辑-首选项-插件-外部命令来打开外部命令,然后在工具-Manage External Tools来添加新工具,工具代码使用bash语言. 代码使用方式:+添加新插件,在编辑框中粘贴代码,快捷 ...

  6. 网课神器之obs-studio的安装使用

    obs-studio 首先,下载obs-studio安装文件,然后点击安装. 建议安装完后直接跳过配置,然后进入文件-设置-通用-系统托盘-勾选"总是最小化到系统托盘,而不是任务栏" ...

  7. java 获取传入值的区间

    /** * 获取值的区间 * * @param num 值 */ public static Map<String, Integer> getNumSection(Integer num) ...

  8. 【JVM之内存与垃圾回收篇】对象实例化内存布局与访问定位

    对象实例化内存布局与访问定位 从各自具体的内存分配上来讲 new 的对象放在堆中 对象所属的类型信息是放在方法区的 方法当中的局部变量放在栈空间 这 new 的对象怎么把三块粘合到一起 就是这章的内容 ...

  9. MapReduce之自定义分区器Partitioner

    @ 目录 问题引出 默认Partitioner分区 自定义Partitioner步骤 Partition分区案例实操 分区总结 问题引出 要求将统计结果按照条件输出到不同文件中(分区). 比如:将统计 ...

  10. 题解 SP1812 【LCS2 - Longest Common Substring II 】

    对于本题这样的多字符串的子串匹配问题,其实用广义后缀自动机就可以很好的解决,感觉会比普通的后缀自动机做法方便一些. 首先记录出每个节点被多少个字符串更新,也就是记录每个节点有多少个字符串能到达它,可以 ...