Android解放双手的利器之ViewBinding

文章目录

    • 1. 背景
    • 2. ViewBinding是什么
    • 3. 开启ViewBinding功能
    • 4. 生成绑定类
    • 5. 使用ViewBinding
      • 5.1Activity 中使用
      • 5.2 Fragment 中使用
      • 5.3 ViewHolder 中使用
    • 6. ViewBinding的优点
    • 7. 与 dataBinding 对比

1. 背景

写代码最繁琐的是什么?重复的机械操作。我们刚接触Android开发时最常写的操作肯定少不了findViewById 的身影。如果页面简单,负担还好,多写几行而已,但如果界面中存在几十上个View呢?再或者,重复的做一件枯燥的事几百次呢?这时候就会敲代码敲到手抽筋,有点生无可恋了吧。

表情包

2. ViewBinding是什么

这时候你的救星它来了!解放你的双手,效率提升十倍!它就是 ViewBinding !

ViewBinding ,顾名思义是“视图绑定”。它可以自动为 XML 布局文件生成一个绑定类,通过这个绑定类,你可以直接拿到布局中的View,再也不用 findViewById 的一个个去找了。

ViewBinding 是AndroidStudio3.6以后就支持的功能,现在大家的Android Studio版本应该都是202x.x.x这种新的年月日版本了吧。Android Studio4.2.2之后就采用这种新版本命名法了。

3. 开启ViewBinding功能

在 module级别的 build.gradle 文件中,添加如下代码:

android {...buildFeatures {viewBinding true}
}

如果你的 build.gradle 是 build.gradle.kts 这种文件,则这样添加代码:

android {...buildFeatures {viewBinding = true}
}

4. 生成绑定类

添加配置代码之后,会提示你点击 sync 同步代码,然后 build 一下工程 AS 会自动为你的工程生成绑定类代码,目录在app/build/generated/data_binding_xxx下。

生成的绑定类命名规则是,将 XML 文件的名称转换为“驼峰命名法”的形式,并在末尾添加“Binding”一词。比如,你的布局文件名是:activity_main.xml,那么生成的绑定类名是: ActivityMainBinding

绑定代码生成

默认情况下,AS会对工程中的所有xml文件生成绑定类。如果不想为某个布局文件生成,则可以将 tools:viewBindingIgnore=“true” 属性添加到该布局文件的根视图中,例如:👇

<LinearLayout...tools:viewBindingIgnore="true" >...
</LinearLayout>

5. 使用ViewBinding

ViewBinding可以用在各种需要布局与代码交互的地方,如Activity、Fragment、ViewHolder等

5.1Activity 中使用

首先是布局,不需要做任何修改😄,比如布局:activity_main.xml👇:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"android:orientation="vertical"tools:context=".MainActivity"><TextViewandroid:id="@+id/tv_title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello World!" /><ImageViewandroid:id="@+id/iv_icon"android:layout_width="100dp"android:layout_height="100dp" /><Buttonandroid:id="@+id/btn_ok"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="按钮" />
</LinearLayout>
  • 使用 ViewBinding 前
    MainActivity.kt 👇:

    import androidx.appcompat.app.AppCompatActivity
    import android.os.Bundle
    import android.widget.Button
    import android.widget.ImageView
    import android.widget.TextViewclass MainActivity : AppCompatActivity() {private var tvTitle: TextView? = nullprivate var ivIcon: ImageView? = nullprivate var btnOk: Button? = nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)tvTitle = findViewById(R.id.tv_title)ivIcon = findViewById(R.id.iv_icon)btnOk = findViewById(R.id.btn_ok)tvTitle?.text = "你好"ivIcon?.setBackgroundColor(Color.RED)btnOk?.text = "确认"btnOk?.setOnClickListener { Toast.makeText(this@MainActivity, "点击了", Toast.LENGTH_SHORT).show()}}
    }
    
  • 使用 ViewBinding 后
    MainActivity.kt 👇:

    import android.graphics.Color
    import androidx.appcompat.app.AppCompatActivity
    import android.os.Bundle
    import android.widget.Toast
    import com.example.mtes.databinding.ActivityMainBindingclass MainActivity : AppCompatActivity() {private var activityMainBinding: ActivityMainBinding? = nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)activityMainBinding = ActivityMainBinding.inflate(layoutInflater)setContentView(activityMainBinding?.root)activityMainBinding?.tvTitle?.text = "你好"activityMainBinding?.ivIcon?.setBackgroundColor(Color.RED)activityMainBinding?.btnOk?.text = "确认"activityMainBinding?.btnOk?.setOnClickListener {Toast.makeText(this@MainActivity, "点击了", Toast.LENGTH_SHORT).show()}}
    }
    

到这里,相信你已经学会了 ViewBinding 的基本用法,体会到它的便捷了吧,再见了 findViewById 😄。

5.2 Fragment 中使用

这里就省略布局的举例了,跟Activity一样,拿到binding后,直接点出来你想访问的view即可。相信聪明的你一定能理解👋

  • 使用 ViewBinding 前,MyFragment.kt 👇:
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroupclass MyFragment : Fragment() {override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {return inflater.inflate(R.layout.fragment_my, container, false)}
}
  • 使用 ViewBinding 后,MyFragment.kt 👇:

    import android.os.Bundle
    import androidx.fragment.app.Fragment
    import android.view.LayoutInflater
    import android.view.View
    import android.view.ViewGroup
    import com.example.mtes.databinding.FragmentMyBindingclass MyFragment : Fragment() {private var binding: FragmentMyBinding? = nulloverride fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {binding = FragmentMyBinding.inflate(layoutInflater, container, false)val view = binding?.rootreturn view}
    }
    

5.3 ViewHolder 中使用

列表也是我们常见的场景,使用 RecyclerView + Adapter + ViewHolder 实现列表,里面少不了对ViewHolder中的View的 findViewById。

比如列表item布局: layout_holder.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"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/tv_item"/>
</LinearLayout>
  • 使用ViewHolder前,MyAdapter.kt👇:

    import android.view.LayoutInflater
    import android.view.View
    import android.view.ViewGroup
    import android.widget.TextView
    import androidx.recyclerview.widget.RecyclerViewclass MyAdapter: RecyclerView.Adapter<MyAdapter.MyViewHolder>() {private val dataList: List<String>? = nullclass MyViewHolder(val itemView: View) : RecyclerView.ViewHolder(itemView) {}override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {val view = LayoutInflater.from(parent.context).inflate(R.layout.layout_holder, parent, false)return MyViewHolder(view)}override fun getItemCount(): Int {return dataList?.size ?: 0}override fun onBindViewHolder(holder: MyViewHolder, position: Int) {val tvText: TextView = holder.itemView.findViewById<TextView>(R.id.tv_item)tvText.text = "你好"}
    }
    
  • 使用ViewHolder后,MyAdapter.kt👇:

    import android.view.LayoutInflater
    import android.view.ViewGroup
    import androidx.recyclerview.widget.RecyclerView
    import com.example.mtes.databinding.LayoutHolderBinding
    class MyAdapter: RecyclerView.Adapter<MyAdapter.MyViewHolder>() {private val dataList: List<String>? = nullclass MyViewHolder(val binding: LayoutHolderBinding) : RecyclerView.ViewHolder(binding.root) {}override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {val binding = LayoutHolderBinding.inflate(LayoutInflater.from(parent.context), parent, false)return MyViewHolder(binding)}override fun getItemCount(): Int {return dataList?.size ?: 0}override fun onBindViewHolder(holder: MyViewHolder, position: Int) {holder.binding.tvItem.text = "标题"}
    }
    

6. ViewBinding的优点

与使用 findViewById 相比,视图绑定具有一些很显著的优点:

  • Null 安全
    由于 ViewBinding 会创建对布局中的 view 的直接引用,因此不存在因 view ID 找不到而引发 null 指针异常的风险.
  • 类型安全
    viewbinding 生成的属性类型和布局中的View类型是一致的,不存在之前findViewById后,类型转换的风险。

7. 与 dataBinding 对比

dataBinding 与 viewBinding 类似,也是可以生成绑定代码,但侧重点在于对于数据的赋值,相比 viewBinding 更复杂一些。因此如果只是想省略 findViewById ,那么推荐用 viewBinding 就好了,因为它有以下优势:

  • 加快编译速度:视图绑定不需要处理注解,因此编译时间更短。
  • 易于使用:视图绑定不需要特别标记的 XML 布局文件,因此在您的应用中采用的速度更快。在模块中启用视图绑定后,它会自动应用于该模块的所有布局。

另一方面,与 dataBinding 相比,viewBinding也有一些劣势:

  • viewBinding 不支持布局变量或布局表达式,因此它不能用于直接从 XML 布局文件声明动态界面内容。
  • viewBinding 不支持双向数据绑定。

最后,dataBinding 与 viewBinding 是可以同时使用的,在哪个页面用哪个,取决于你喽🤣。

怎么样,有了 ViewBinding,妈妈再也不用担心你的手指了,快去试试吧~
如果这篇文章对你有用,欢迎支持🙏

官网文档:https://developer.android.google.cn/topic/libraries/view-binding#groovy

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

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

相关文章

Docker搭建ctfd平台

安装docker和docker-compose &#xff08;1&#xff09;安装docker&#xff1a; curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun&#xff08;2&#xff09;安装 Docker Compose&#xff1a; yum install docker-compose安装失败参考下面文章 https:/…

二叉搜索树模拟实现

目录 认识二叉搜索树&#xff1a; 模拟实现&#xff1a; 节点结构体构建&#xff1a; insert&#xff08;插入&#xff09;: find&#xff08;查找&#xff09;&#xff1a; erase&#xff08;删除&#xff09;&#xff08;重点&#xff09;&#xff1a; 全部代码 认识二叉…

第十一讲:指针(3)

第十一讲&#xff1a;指针&#xff08;3&#xff09; 1.字符指针变量1.1存储一个字符1.2存储一个字符串1.3一个有趣的面试题 2.数组指针变量2.1什么是数组指针变量2.2数组指针变量的初始化 3.二维数组传参的本质4.函数指针变量4.1介绍函数指针变量4.2 两段有趣的代码4.2.1代码1…

内容安全(AV)

防病毒网关&#xff08;AV&#xff09;简介 基于网络侧 识别 病毒文件&#xff0c;工作范围2~7层。这里的网关指的是内网和外网之间的一个关口&#xff0c;在此进行病毒的查杀。在深信服中就有一个EDR设备&#xff0c;该设备就是有两种部署&#xff0c;一个部署在网关&#xf…

Java----数组的定义和使用

1.数组的定义 在Java中&#xff0c;数组是一种相同数据类型的集合。数组在内存中是一段连续的空间。 2.数组的创建和初始化 2.1数组的创建 在Java中&#xff0c;数组创建的形式与C语言又所不同。 Java中数组创建的形式 T[] 数组名 new T[N]; 1.T表示数组存放的数据类型…

FPGA学习笔记(1)——Vivado和HLS

1 Vivado设计 1.1 FPGA基本知识 Xilinx Atrix-7使用6输入LUT结构&#xff08;0-63&#xff09;CLB&#xff1a;可配置逻辑块Slice&#xff1a;每个CLB包含2个Slice(包含查找表LUT和8位寄存器REG)布线池&#xff1a;围绕在CLB周围&#xff0c;衔接FPGA的资源调度I/O块&#xf…

vivado Spartan-7 配置存储器器件

下表所示闪存器件支持通过 Vivado 软件对 Spartan -7 器件执行擦除、空白检查、编程和验证等配置操作。 本附录中的表格所列赛灵思系列非易失性存储器将不断保持更新 &#xff0c; 并支持通过 Vivado 软件对其中所列非易失性存储器 进行擦除、空白检查、编程和验证。赛灵…

带EXCEL附件邮件发送相关代码

1.查看生成的邮件 2.1 非面向对象的方式&#xff08;demo直接copy即可&#xff09; ​ REPORT Z12. DATA: IT_DOCUMENT_DATA TYPE SODOCCHGI1,IT_CONTENT_TEXT TYPE STANDARD TABLE OF SOLISTI1 WITH HEADER LINE,IT_PACKING_LIST TYPE TABLE OF SOPCKLSTI1 WITH HEADER LIN…

在做题中学习(57):寻找数组的中心下标

724. 寻找数组的中心下标 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a;前缀和后缀和 思路&#xff1a;要看一个数是不是中心下标&#xff0c;就看他前面数的和 与 后面数的和 相不相等。 1.i前面数的和&#xff0c;是[0,i-1] 的前缀和&#xff0c;i后面数的和&am…

快递物流查询:如何实现快递批量查询?这些技巧助你轻松应对

在日常生活和工作中&#xff0c;我们经常需要查询快递物流信息&#xff0c;尤其是当面对大量的快递包裹时&#xff0c;逐一查询无疑会耗费大量的时间和精力。这时&#xff0c;实现快递批量查询就显得尤为重要。本文将为你介绍办公提效工具一些实现快递批量查询的技巧&#xff0…

国内有哪些知名的网络安全厂商?

首先就是360&#xff0c;这个我相信大家并不陌生了吧&#xff0c;你的电脑装过360么&#xff1f; 360在个人终端服务那是妥妥的扛把子&#xff0c;但是在企业服务里虽然有他们的身影却略显不足。 第二个就是深信服&#xff0c;网络安全的老牌大佬&#xff0c;业务覆盖了全球5…

【数据分析】 JupyterNotebook安装及使用简介

各位大佬好 &#xff0c;这里是阿川的博客 &#xff0c; 祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 在数据分析中&#xff0c;一般用Pycharm编辑代…

18 分页:介绍

目录 简单例子 页表存在哪里 列表中究竟有什么 分页&#xff1a;也很慢 内存追踪 小结 在解决大多数空间管理问题上面&#xff0c;操作系统有两种方法&#xff1a; 第一种就是将空间分割成不同长度的分片&#xff0c;类似于虚拟内存管理中的分段&#xff0c;但是这个方法…

MySQL45讲(一)(40)

回顾binlog_formatstatement STATEMENT 记录SQL语句。日志文件小&#xff0c;节约IO&#xff0c;但是对一些系统函数不能准确复制或不能复制&#xff0c;如now()、uuid()等 在RR隔离级别下&#xff0c;binlog_formatstatement 如果执行insert select from 这条语句是对于一张…

win10禁止自动更新的终极方法

添加注册表值 1.运行&#xff0c;输入regedit 2.打开注册表编辑器依次进入以下路径“计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings”。 3.在Settings项中&#xff0c;新建DWORD&#xff08;32位&#xff09;值(D)&#xff0c;重命名为以下命名“Fl…

vuex核心概念-getters

除了state之外&#xff0c;有时我们还需要从state中派生出一些状态&#xff0c;这些状态是依赖state的&#xff0c;此时会用到getters。

2023版brupsuite专业破解安装

安装教程&#xff0c;分两部分&#xff1a; 1、安装java环境、参考链接JAVA安装配置----最详细的教程&#xff08;测试木头人&#xff09;_java安装教程详细-CSDN博客 2、安装2023.4版本brupsuite&#xff1a;参考链接 2023最新版—Brup_Suite安装配置----最详细的教程&…

实体同城商家短视频获客,3天直播课,玩转实体商家私域,引爆门店增长

课程内容&#xff1a; 实体同城3天直播课【资料】 实体商家获客第一天 .mp4 实体商家获客第二天上.mp4 实体商家获客第二天,mp4 实体商家获客第三天.mp4 实体商家获客第4天.mp4 网盘自动获取 链接&#xff1a;https://pan.baidu.com/s/1lpzKPim76qettahxvxtjaQ?pwd0b8x…

数据结构----二叉树

博主主页: 码农派大星. 关注博主带你了解更多数据结构知识 1. 树型结构 1.1 概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上…

对Windows超融合S2D的一些补充

先说一个不知道算不算BUG的例子&#xff0c;下面这个存储池是用两台服务器各2块10G建立的&#xff0c;除去系统保留的部分&#xff0c;显示还有13G可用。 但如果使用其新建虚拟磁盘会显示可用的空间为0 然后我又各增加了一块10G硬盘进池&#xff0c;变成了可用空间为30.5GB …