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.hqwc.cn/news/687873.html

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

相关文章

使用apache和htaccess对目录访问设置密码保护配置教程

对目录设置密码保护配置说明 我们有时候访问某些网站的时候&#xff0c;要求输入用户名和密码才能访问。这是为了保护隐私&#xff0c;只让经过许可的人访问。 在本教程中主要介绍两种方法&#xff0c;一种是通过apache httpd.conf配置文件对管理后台目录设置密码保护&#xff…

设置多用户远程登录windows server2016服务器

1、远程登录windows server 2016 运行—>mstsc—>远程IP地址—>用户和密码 2、远程windows服务器设置多用户策略 运行—>gpedit.msc->计算机配置—管理模板—windows组件—远程桌面服务—远程桌面会话主机----连接,如下图所示: 1、《限制连接的数量》设置为…

hadoop大数据的一些知识点--Map reduce编程

实验4 MapReduce编程(2) 本实验的知识地图如图4-1所示&#xff08; 表示重点 表示难点&#xff09;。 图4-1 实验4MapReduce编程(2)知识地图 一、实验目的 1. 理解YARN体系架构。 2. 熟练掌握YARN Web UI界面的使用。 3. 掌握YARN Shell常用命令的使用。 4. 了解YARN编程之…

Secnet-智能路由系统 actpt_5g.data 信息泄露漏洞复现

0x01 产品简介 Secnet安网智能AC管理系统是广州安网通信技术有限公司&#xff08;简称“安网通信”&#xff09;的无线AP管理系统。 0x02 漏洞概述 Secnet-智能路由系统 actpt_5g.data 接口存在信息泄露漏洞&#xff0c;未经身份验证的远程攻击者可以利用此漏洞获取系统账户…

redis抖动问题导致延迟或者断开的处理方案

目录&#xff1a; 1、使用背景2、redis重试机制3、redis重连机制4、其他一些解决redis抖动问题方案 1、使用背景 客户反馈文件偶现打不开&#xff0c;报错现象是session not exist&#xff0c;最终定位是redis抖动导致的延迟/断开的现象&#xff0c;最终研发团方案是加入redis…

泰迪智能科技企业数据挖掘流程分析及特色服务优势

企业发展会沉淀大量的数据&#xff0c;数据中囊括了企业业务各种维度指标&#xff0c;通过数据挖掘和数据分析 &#xff0c;让企业业务了解过去、现在和未来将要发生什么&#xff0c;从而更好的调整企业发展方向。泰迪智能科技企业数据挖掘平台是面向企业级用户快速处理数据构建…

ssrf学习2——内网ip绕过

环回地址绕过 尝试访问内网 也就是127.0.0.1里面的flag.php 但是如果真的去访问127.0.0.1/flag.php 还是不行 也就是说127.0.0.1被过滤了 进制转换 127.0.0.1是点分十进制 可以用二进制八进制十六进制来绕过过滤 0x7F000001/flag.php 017700000001/flag.php(八进制前面是…

李彦宏回顾大模型重构百度这一年

“大模型我们走在最前面&#xff0c;我们需要去勇闯无人区&#xff0c;需要去冒前人没有冒过的风险。”近日&#xff0c;在百度一场内部颁奖活动中&#xff0c;百度创始人、董事长兼首席执行官李彦宏指出&#xff0c;百度一直坚信技术可以改变世界&#xff0c;会一直沿着这条路…

Canvas绘制图片和区域(前端使用Canvas绘制图片,并在图片上绘制区域)

简介&#xff1a;在Web开发中&#xff0c;有时候我们需要在图片上进行一些交互式操作&#xff0c;比如绘制区域、标记等。这种场景下&#xff0c;我们可以使用HTML5的<canvas>元素来实现。Canvas 是 HTML5 提供的一种图形绘制接口&#xff0c;可以通过 JavaScript 在网页…

Allegro如何输出各层PCB视图的PDF文件

如何输出各层PCB视图的PDF文件 1、说明 用Allegro设计好PCB后&#xff0c;有时需要出各层的PDF文档出来进行汇报和展示&#xff0c;这时就需要将各层的平面视图全部以PDF的形式加载出来&#xff0c;具体方法如下。 2、PDF文件的输出方法&#xff08;以四层板为例&#xff09; …

C——单链表

一.前言 我们在前面已经了解了链表中的双向链表&#xff0c;而我们在介绍链表分类的时候就说过常用的链表只有两种——双向带头循环链表和单向不带头不循环链表。下来我来介绍另一种常用的链表——单向不带头不循环链表也叫做单链表。不清楚链表分类的以及不了解双向链表的可以…

【bug记录】Vue3 Vant UI 中 van-popup 不弹出

原因&#xff1a;语法使用错误&#xff0c;使用了 Vue 2 的语法 Vue3语法&#xff1a; Vue2语法&#xff1a;