将视图转为image_使用视图绑定替代 findViewById

b664ef8d1d3995870ffd4af67cefdf0c.png

从 Android Studio 3.6 开始,视图绑定能够通过生成绑定对象来替代 findViewById,从而可以帮您简化代码、移除 bug,并且从 findViewById 的模版代码中解脱出来。

本文梗概

  • 在 build.gradle 中就可以方便快捷地开启视图绑定且无须额外引入依赖库
  • 视图绑定会为 Module 中的每一个布局文件生成一个绑定对象 (activity_awesome.xml → ActivityAwesomeBinding.java)
  • 布局文件中每一个带有 id 的视图都会在绑定对象中有一个对应的属性,这个属性将拥有正确的类型,并且空安全
  • 视图绑定完美支持 Java 和 Kotlin 编程语言

更多详细内容可以从视频:使用视图绑定替代 findViewById 中获取。

在 build.gradle 中开启视图绑定

开启视图绑定无须引入额外依赖,从 Android Studio 3.6 开始,视图绑定将会内建于 Android Gradle 插件中。需要打开视图绑定的话,只需要在 build.gradle 文件中配置 viewBinding 选项:

// 需要 Android Gradle Plugin 3.6.0android {    viewBinding {        enabled = true    }}

在 Android Studio 4.0 中,viewBinding 变成属性被整合到了 buildFeatures 选项中,所以配置要改成:

// Android Studio 4.0android {    buildFeatures {        viewBinding = true    }}

配置完成后,视图绑定就会为所有布局文件自动生成对应的绑定类。无须修改原有布局的 XML 文件,视图绑定将根据您现有的布局自动完成所有工作。

视图绑定将会根据现有的 XML 文件,为 Module 内所有的布局文件生成绑定对象。

您可以在任何需要填充布局的地方使用绑定对象,比如 Fragment、Activity、甚至是 RecyclerView Adapter(或者说是 ViewHolder 中)。

在 Activity 中使用视图绑定

假如您有一个布局文件名叫 activity_awesome.xml,其中包含了一个按钮和两个文本视图。视图绑定会为这个布局生成一个名叫 ActivityAwesomeBinding 的类,布局文件中所有拥有 id 的视图,都会在这个类中有一个对应的属性:

override fun onCreate(savedInstanceState: Bundle?) {    super.onCreate(savedInstanceState)    val binding = ActivityAwesomeBinding.inflate(layoutInflater)    binding.title.text = "Hello"    binding.subtext.text = "Concise, safe code"    binding.button.setOnClickListener { /* ... */ }    setContentView(binding.root)}

△ 在 Activity 中使用视图绑定

使用视图绑定时,无须再调用 findViewById 方法,只要直接调用绑定对象中的对应属性即可。

布局的根视图(无论有没有 id)都会自动生成一个名为 root 的属性。在 Activity 的 onCreate 方法中,要将 root 传入 setContentView 方法,从而让 Activity 可以使用绑定对象中的布局。

一个常见的错误用法是: 在开启了视图绑定的同时,依然在 setContentView(...) 中传入布局的 id 而不是绑定对象。这将造成同一布局被填充两次,同时监听器也会被添加到错误的布局对象中。

解决方案: 在 Activity 中使用视图绑定时,一定要将绑定对象的 root 属性传入 setContentView() 方法中。

使用绑定对象编写安全性更佳的代码

findViewById 是许多用户可见 bug 的来源: 我们很容易传入一个布局中根本不存在的 id,从而导致空指针异常而崩溃;由于此方法类型不安全,也很容易使人写出像 findViewById(R.id.image) 这样的,导致类型转换错误的代码。为了解决这些问题,视图绑定把 findViewById 替换成了更加简洁和安全的实现。

视图绑定有下面两个特性:

  • 类型安全: 因为视图绑定总是会基于布局中的视图生成类型正确的属性。所以如果您在布局中放入了一个 TextView ,视图绑定就会暴露一个 TextView 类型的属性给您。
  • 空安全: 视图绑定会检测某个视图是不是只在一些配置下存在,并依据结果生成带有 @Nullable 注解的属性。所以即使在多种配置下定义的布局文件,视图绑定依然能够保证空安全。

由于生成的绑定类是普通的 Java 类,并且其中添加了 Kotlin 友好的注解,所以 Java 和 Kotlin 都可以使用视图绑定。

视图绑定生成的代码是怎样的

如前文所说,视图绑定会生成一个包含替代 findViewById 功能的 Java 类。它会为 Module 下的每一个布局的 XML 文件生成一个对应的绑定对象,并根据源文件为其命名,比如 activity_awesome.xml 对应的绑定对象为 ActivityAwesomeBinding.java。

生成代码的逻辑被优化为,当您在 Android Studio 中编辑 XML 布局文件时,只会更新所修改布局对应的绑定对象。同时这些工作会在内存中运行,从而使这个过程可以迅速完成。这意味着您的修改会立即反映在绑定对象中,而无须等待或者重新构建工程。

Android Studio 被优化为可以在您编辑过 XML 布局文件后立即更新绑定对象。

让我们通过一个 示例 XML 布局 所生成的代码,来了解一下视图绑定究竟生成了什么。

public final class ActivityAwesomeBinding implements ViewBinding {  @NonNull  private final ConstraintLayout rootView;  @NonNull  public final Button button;  @NonNull  public final TextView subtext;  @NonNull  public final TextView title;

△ 视图绑定生成的属性。可以看到它们都是类型安全以及空安全的

视图绑定会根据每个拥有 id 的视图生成类型正确的属性。他也会为根布局生成 rootView 属性并通过 getRoot 暴露给您。视图绑定没有添加任何额外的逻辑,他只是把视图属性暴露给您,从而帮您在不使用 findViewById 的情况下也能调用它们。这样一来便保证了生成文件简洁性(当然也避免了拖慢构建速度)。

如果您正在使用 Kotlin,视图绑定的生成类也已经对互操作进行了优化。通过 @Nullable 和 @NonNull 注解的使用,Kolin 可以正确的将属性暴露为空安全类型。如果想要了解更多关于两种语言的互操作问题,请查阅文档: 在 Kotlin 中调用 Java。

  private ActivityAwesomeBinding(@NonNull ConstraintLayout rootView, @NonNull Button button,      @NonNull TextView subtext, @NonNull TextView title) { … }  @NonNull  public static ActivityAwesomeBinding inflate(@NonNull LayoutInflater inflater) {    /* 编辑过: 移除了重载方法 inflate(inflater, parent, attachToParent) 的调用*/    View root = inflater.inflate(R.layout.activity_awesome, null, false);    return bind(root);  }

视图绑定会生成 inflate 方法作为生成一个绑定对象实例的主要方式。在 ActivityAwesomeBinding.java 中,视图绑定生成了一个只有一个参数的 inflate 方法,该方法通过将 parent 设定为空值来指定当前视图不会绑定到父视图中;视图绑定也暴露了一个有三个参数的 inflate 方法,来让您在需要的时候传入 parent 和 attachToParent 参数。

真正神奇的地方是 bind 方法的调用。这里会填充视图并绑定所有的属性,同时做一些错误检测并生成清晰的错误提示。

 @NonNull public static ActivityAwesomeBinding bind(@NonNull View rootView) {    /* 编辑: 简化代码 – 真实情况下生成的代码是一个优化过的版本 */    Button button = rootView.findViewById(R.id.button);    TextView subtext = rootView.findViewById(R.id.subtext);    TextView title = rootView.findViewById(R.id.title);    if (button != null && subtext != null && title != null) {      return new ActivityAwesomeBinding((ConstraintLayout) rootView, button, subtext, title);    }    throw new NullPointerException("Missing required view […]");}

△ 自动生成的 bind 方法的简化版本

bind 是绑定对象中最复杂的一个方法,它通过调用 findViewById 来绑定每个视图。既然编译器可以通过 XML 布局文件知道每个属性的类型和为空的可能性,那他就可以安全的调用 findViewById。

请注意,视图绑定生成的真正的 bind 方法要来的更长,并且其中使用了一个标记 break 语句来优化字节码,您可以查看 Jake Wharton 撰写的这篇文章 来了解更多优化有关的内容。在每个绑定对象中,都会暴露三个静态方法来创建绑定对象实例,下面是每个方法使用场景的简要说明:

  • inflate(inflater) -- 在例如 Activity onCreate 方法里,这类没有父视图需要被传入的场合使用
  • inflate(inflater, parent, attachToParent) -- 在 Fragment 或 RecyclerView Adapter (或者说 ViewHolder 中) ,这类您需要传递父级 ViewGroup 给绑定对象时使用。
  • bind(rootView) -- 在您已经获得对应视图,并且只想通过视图绑定来避免使用 findViewById 时使用。这个方法在使用视图绑定改造和重构现有代码时非常有用。

对使用include标签引入的布局会发生什么影响

前面已经讲过,视图绑定会为 Module 下的每一个布局文件生成一个绑定对象,这个说法在布局文件被另一个布局文件使用 include 引入时依然适用。

        

△ 视图绑定中使用 include 标签的示例 注意: include 标签下有一个 id。

在使用引入布局的时候,视图绑定会创建一个被引入布局绑定对象的引用。注意 include>标签有一个 id: android:id="@+id/includes"。这里的逻辑跟使用普通视图一样, include 标签也需要有一个 id 才能在绑定对象中生成对应的属性。

include 标签必须有一个 id,才能生成对应的属性。

public final class ActivityAwesomeBinding implements ViewBinding {  ...  @NonNull  public final IncludedButtonsBinding includes;

视图绑定会在 ActivityAwesomeBinding 中生成一个 IncludedButtonsBinding 的引用。

结合数据绑定来使用视图绑定

视图绑定只是 findViewById 的取代方案,如果您希望在 XML 中自动绑定视图,可以使用 数据绑定 库。数据绑定和视图绑定可以生成同样的组件,它们可以同时工作。

在两者都被开启时,使用 标签的布局会由数据绑定来生成绑定对象;而其余的布局则由视图绑定生成绑定对象。

您可以在同一 Module 中同时使用数据绑定和视图绑定。

我们之所以开发视图绑定作为数据绑定的补充,是因为许多开发者反映说,希望有一个轻量的解决方案,能在数据绑定之外替代 findViewById——视图绑定提供的正是这一功能。

视图绑定对比 Kotlin 合成方法与 ButterKnife

关于视图绑定,一个最常见的问题是: "我是否应该用视图绑定替代 Kotlin 合成方法或 ButterKnife ? " 二者都是目前十分成功的组件库,有许多应用使用它们解决 findViewById 的问题。

对于大多数应用来说,我们推荐尝试使用视图绑定来替代这两个库,因为视图绑定可以提供更加安全和准确的视图映射方式。

046cb2c23d6ffaedfecfaff10d969803.png

△ 视图绑定空安全、只引用当前布局中的视图、支持 Java 和 Kotlin,同时也更简洁

上图为对比视图绑定、ButterKnife 和 Kotlin 合成方法的功能。

虽然 ButterKnife 会在运行时校验可空与不可空,但是编译器并不会检查您匹配的视图是否在存在于您的布局之中。

为了安全性与更简洁代码,我们推荐尝试使用视图绑定。

点击这里了解更多有关视图绑定的信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/571299.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2.6 子窗口赋值给父窗口并关闭子窗口 我的程序猿之路:第十六章

<s:textfield id"innovationName" cssClass"txt validate[maxSize[50]]"title"请选择创新岗位" readonly"true"><a onmouseover"changeStyle(this)" onmouseout"addStyle(this)" class"btna agree…

第二专业 计算机考试成绩查询系统,2021年上半年信息系统项目管理师成绩查询时间公布(7月12日),查询入口已开通!...

2021年上半年信息系统项目管理师成绩查询时间公布!2021年7月12日上午11点3分48秒&#xff0c;软考办官网发布了2021年上半年计算机技术与软件专业技术资格(水平)考试成绩查询通知。2021年上半年信息系统项目管理师成绩查询入口开通!赶快来查成绩吧!2021年上半年信息系统项目管理…

本周数据与上周对比应如何表达_互联网运营中的数据分析方法

在大数据分析和产品、运营优化方面&#xff0c;大数据分析方法是其核心&#xff0c;那么如何做好数据分析呢&#xff0c;今天我们来讲讲互联网运营中的数据分析方法。1.细分分析细分分析是分析的基础&#xff0c;单一维度下的指标数据的信息价值很低。细分方法可以分为两类&…

Python - 装饰器

Python - 装饰器转载于:https://www.cnblogs.com/LouisZJ/p/8250271.html

计算机开启后显示器黑屏,电脑启动后,显示器马上黑屏,又马上有画面,每次启动都是这样...

灯管的问题好检测&#xff5e;你将周围的环境搞暗些&#xff5e;从各个不同位置贴近看液晶显示屏幕&#xff5e;隐约能看见有字迹画面什么的就说明是灯管的问题啦&#xff5e;反之就是高压板其它问题啦&#xff5e;祝楼主好运&#xff5e;回复:现在能够正常使用么&#xff1f;开…

git小技巧之分支、关联远程仓库、回滚、解决.gitignore不生效等

1、分支管理 新建并切换分支&#xff1a;git checkout -b <name>新建本地分支并关联到远程分支git checkout -b myRelease origin/Release合并某分支到当前分支git merge myRelease (--no-ff)提交到远程分支 git push --set-upstream origin myRelease删除远程分支git pu…

惠斯通电桥信号调理芯片_elmos推出专为汽车应用开发的传感器信号调理芯片E520.47...

——符合标准ISO26262 &#xff0c;达到ASIL C等级2019年3月&#xff0c;德国巴伐利亚州慕尼黑讯&#xff0c;elmos日前宣布推出E520.47&#xff0c;这是一款带有SENT接口的传感器信号调理IC&#xff0c;支持两路电阻式传感器电桥的同步信号处理。该IC专为汽车应用的需求而开发…

lab 2 EIGRP Default Route

EIGRP发布默认路由的四种方式Redistributed default route #R1# router eigrp 100redistribute static network 10.1.1.1 0.0.0.0no auto-summary ip route 0.0.0.0 0.0.0.0 202.100.1.10By using ip summary-address command #interface FastEthernet1/0ip address 10.1.1.1 2…

今天英雄联盟服务器维护要到好久,lol今天维护时间是多久 lol维护公告2020最新...

英雄联盟今天维护到几点?今日维护时间是多久?lol维护公告2020最新消息来啦!英雄联盟在4月16日凌晨1点进行了游戏的停机更新。下面&#xff0c;就和小编一起来了解一下最新的维护内容吧!lol10.8版本维护到几点LOL将在4月16日凌晨1点关闭排位赛入口(不影响已经在进行中的对局)&…

开关怎么使用_水龙头漏水怎么办?使用时把控开关力度很重要

水龙头漏水是家居生活中器件中常见的故障之一&#xff0c;导致水龙头漏水的原因有很多&#xff0c;严重就需要我们更换新的水龙头了。水龙头漏水怎么办呢?其实&#xff0c;我们掌握一些家居生活的知识也是对我们很有帮助的&#xff0c;下面是水龙头漏水的解决办法以及预防措施…

黑域,黑阈 Permission denied

在执行&#xff1a; adb -d shell sh /data/data/me.piebridge.brevent/brevent.sh 时遇到Permission denied&#xff0c;多运行一次就好了。 完整的有两条命令&#xff1a; adb devicesadb -d shell sh /data/data/me.piebridge.brevent/brevent.sh 转载于:https://www.cnblog…

fast路由器服务器未响应,win7系统下fast路由器进不了设置界面如何解决

最近有不少win7纯净版系统用户到本站反馈说碰到这样一个问题&#xff0c;就是在使用fast路由器的时候&#xff0c;进不了设置界面&#xff0c;导致无法进行一系列设置&#xff0c;该怎么办呢&#xff0c;接下来给大家讲解一下win7系统下fast路由器进不了设置界面的具体解决方法…

xshell堡垒机_Jumpserver开源堡垒机管理

此篇文章主要介绍jumpserver开源堡垒机管理&#xff0c;安装请移至&#xff1a;Jumpserver开源堡垒机安装一、用户管理1)添加用户1输入要添加的用户名&#xff0c;姓名&#xff0c;权限&#xff0c;Mail&#xff0c;并且发送邮件 —> 确认保存23查看添加的用户4查看用户邮件…

解决连接mysql报错1130

最近在服务器上部署好的应用突然间连接不上mysql数据库&#xff0c;报错“ERROR 1130: Host xxx.xxx.xxx.xxx is not allowed to connect to this MySQL server” 那么直接运行如下命令&#xff1a; mysql -u root -p 弹出Enter password:输入您的数据库密码 链接到mysql数据库…

python 多组直方图 画图_python – 使用matplotlib的多个并排直方图?

我有一个软件必须处理大量不同的数据,并且可能需要不同的时间来处理它.随着软件的修改,处理数据所需的时间也会发生变化,所以我想创建一个显示时间差异和异常值的图表,因为理想情况下,这个程序每个部分需要大约相同的时间数据(这听起来很奇怪,不切实际,我知道,但在这里和我一起…

vnc连接服务器怎么配置文件,vnc服务器和客户端怎么配置文件

vnc服务器和客户端怎么配置文件 内容精选换一换用户通过psycopy2连接GaussDB(for openGauss)服务器时&#xff0c;可以通过开启SSL加密客户端和服务器之间的通讯。在使用SSL时&#xff0c;默认用户已经获取了服务端和客户端所需要的证书和私钥文件&#xff0c;关于证书等文件的…

shell题库选择题_shell学习:几道常见shell习题

1. 编写shell脚本&#xff0c;计算1-100的和&#xff1b;1 #! /bin/bash2 sum03 for i in seq 1 100; do4 sum$[$i$sum]5 done6 echo $sum计算-00和2. 编写shell脚本&#xff0c;要求输入一个数字&#xff0c;然后计算出从1到输入数字的和&#xff0c;要求&#xff0c;如果输入…

服务器主板稳定,服务器主板

Intel Atom™ C3000 Mini-ITX 服务器主板&#xff0c;带 4 个DDR4 DIMM, 1 个 PCIe x4插槽 (Gen 3.0), 8 个SATA III, IPMILGA 1151 Intel Xeon E3 v5/ v6 Core™ i 6代/7代 Micro ATX 服务器主板&#xff0c;带4 个DDR4&#xff0c;1 个PCIe x 16&#xff0c;3 个PCIe x 4&am…

Extjs grid 设置行字体颜色

CustSuppGrid Ext.create(Ext.grid.Panel, {title : , // 标题头iconCls : icon-grid, // 标题图标store : CustSuppStore, // 数据源frame : false, // True 为 Panel 填充画面,默认为falseforceFit : false, // 设置为true,则强制列自适应成可用宽度selType : checkboxmodel…

诚龙网刻报错_诚龙PXE网刻工具11.5

终于等到您&#xff01;马上注册登录,做有身份的人&#xff01;您需要 登录 才可以下载或查看&#xff0c;没有帐号&#xff1f;注册账号扫一扫&#xff0c;用微信登录x使用诚龙网维全自动PXE网刻工具进行网刻&#xff0c;你无须架设DHCP和TFTP服务器&#xff0c;也无须进行GHS…