安卓ViewBinding详解

article/2025/8/24 7:51:43

背景

之前我们通过Kotlin Android Extensions来访问布局文件中的元素,但是这个现在被废弃了,原因如下:

  1. 空安全:res下的任何id都可以被访问,有可能因访问了非当前Layout下的id而出错
  2. 兼容性:只能在kotlin中使用,java不能用
  3. 局限性:不能跨模块使用

访问布局中元素方法

  1. findViewById
  2. ButterKnife
  3. DataBinding
  4. Kotlin Android Extensions
  5. ViewBinding

ViewBinding

2019年Google I/O大会上公布的一款Android视图绑定工具:ViewBinding。使用方式类似DataBinding,但相比DataBinding,ViewBinding是一个更轻量级、更纯粹的findViewById的替代方案。它具有如下优点:

  1. 类型安全: ViewBinding会基于布局中的View生成类型正确的属性。比如,在布局中放入了一个 TextView ,视图绑定就会暴露出一个 TextView 类型的属性供开发中使用。
  2. 空安全:ViewBinding会检测某个视图是否只在某些配置下存在,并依据结果生成带有 @Nullable 注解的属性,所以即使在多种配置下定义的布局文件,视图绑定依然能够保证空安全。
  3. ViewBinding生成的绑定类是一个Java类,并且添加了Kotlin注解,可以很好地支持 Java 和 Kotlin 两种编程语言。

使用详解

  1. Activity中基础使用方式
  • 修改build.gradle文件
    在android节点下增加buildFeatures 信息,具体如下:
android {...buildFeatures {viewBinding = true}
}
  • Activity中调用方式
class MainActivity : AppCompatActivity() {private lateinit var binding: ActivityMainBindingoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding = ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)binding.textView1.text = "textView1"}
}

注意:ActivityMainBinding是根据布局文件activity_main.xml来生成的。

  • 代码变化点说明
    之前的setContentView(R.layout.activity_main)修改为了:
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)

访问布局文件中元素时,使用:binding.textView1这样的命名方式即可。
2. 布局中引用其他布局

  • 主布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextViewandroid:id="@+id/textView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="111111" /><includeandroid:id="@+id/subView"layout="@layout/view_sub" />
</LinearLayout>

注意:必须要给被引用布局设置id属性。

  • 被引用布局文件view_sub.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><TextViewandroid:id="@+id/textView2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="222222" />
</LinearLayout>
  • 调用方法
binding.subView.textView2.text = "textView2"
  1. 引用merge布局
  • 主布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextViewandroid:id="@+id/textView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="111111" /><include layout="@layout/view_merge" />
</LinearLayout>
  • 被引用布局文件view_merge.xml
<merge xmlns:android="http://schemas.android.com/apk/res/android"><TextViewandroid:id="@+id/textView3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="333333" />
</merge>
  • 调用方法
class MainActivity : AppCompatActivity() {private lateinit var binding: ActivityMainBindingprivate lateinit var viewMergeBinding: ViewMergeBindingoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding = ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)viewMergeBinding = ViewMergeBinding.bind(binding.root)viewMergeBinding.textView3.text = "textView3"}
}
  1. 在Activity基类中使用
  • 基类BaseActivity
abstract class BaseActivity<T : ViewBinding> : AppCompatActivity() {protected lateinit var binding: Tabstract fun initBinding(): Tabstract fun init()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)binding = initBinding()setContentView(binding.root)init()}
}
  • 子类MainActivity
class MainActivity : BaseActivity<ActivityMainBinding>() {override fun initBinding() = ActivityMainBinding.inflate(layoutInflater)override fun init() {binding.textView1.text = "textView1"}
}
  1. Fragment用法
  • 布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@android:color/holo_blue_light"android:gravity="center"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="第一个Fragment" /></LinearLayout>
  • 调用方式
class FirstFragment : Fragment() {private var _binding: FragmentFirstBinding? = nulloverride fun onCreateView(inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?): View? {_binding =FragmentFirstBinding.inflate(LayoutInflater.from(container?.context), container, false)return _binding?.root}override fun onDestroyView() {_binding = nullsuper.onDestroyView()}
}
  1. Fragment基类用法
  • 布局文件同上
  • 调用方式
class FirstFragment : BaseFragment<FragmentFirstBinding>() {override fun initBinding() = FragmentFirstBinding.inflate(layoutInflater)override fun init() {_binding?.textView1?.text="textView1"}
}
  1. RecyclerView中使用
    篇幅有限,只列出有变化的Adapter类:
class RvAdapter : RecyclerView.Adapter<RvAdapter.MyViewHolder>() {private var mDataList = mutableListOf<String>()private lateinit var mContext: Contextoverride fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {mContext = parent.contextval itemBinding =ItemLayoutBinding.inflate(LayoutInflater.from(parent.context), parent, false)return MyViewHolder(mContext, itemBinding)}override fun onBindViewHolder(viewHolder: MyViewHolder, position: Int) {val data = mDataList[position]viewHolder.bind(data)}fun setData(dataList: List<String>) {mDataList.clear()mDataList.addAll(dataList)notifyDataSetChanged()}override fun getItemCount(): Int = mDataList.sizeclass MyViewHolder(private var context: Context, private var itemBinding: ItemLayoutBinding) :RecyclerView.ViewHolder(itemBinding.root) {fun bind(data: String) {//更新UI上nameTv展示内容itemBinding.nameTv.text = data//设置点击事件itemBinding.root.setOnClickListener {Toast.makeText(context, data, Toast.LENGTH_SHORT).show()}}}
}

关于我

厦门大学计算机专业|华为八年高级工程师
十年软件开发经验,5年编程培训教学经验
目前从事编程教学,软件开发指导,软件类毕业设计指导。

参考资料

https://blog.csdn.net/qq_20521573/article/details/110278319
https://weilu.blog.csdn.net/article/details/109557820
https://www.jianshu.com/p/f284dd13b953


http://chatgpt.dhexx.cn/article/PBbrxSJ3.shtml

相关文章

Winform中用bindingNavigator和bingdingSource实现分页

BindingNavigator控件介绍 可以使用BindingNavigator控件来创建标准化的方法&#xff0c;以便用户搜索和更改 Windows 窗体上的数据。BindingNavigator 控件由包含一系列 ToolStripItem 对象的ToolStrip组成&#xff0c;可以实现&#xff1a;添加数据&#xff0c;删除数据&…

DataGridView使用bindingNavigator实现分页功能(应用存储过程)

想法是这样的&#xff1a;使用bindingNavigator存储过程实现DataGridView的分页功能&#xff0c;其中包含简单的查询。 存储过程如下&#xff1a; --创建分页查询存储过程(含输出参数&#xff0c;输入参数&#xff08;含搜索功能&#xff09;) use HotelDB if exists(select *…

配置bind

安装bind yum install bind-* service firewalld stop #暂时关闭防火墙 vim /etc/named.conf Linsten-on port 53 {any;}; 监听除了自己以外的ip Allow-query{any&#xff1b;} 允许任意的ip来访问 配置正向解析 /etc/named.rfc1912.zones #直接在底部添加 zone "s…

Android dataBinding和viewBinding的混淆配置

在最近重构过的项目中有使用dataBinding或viewBinding&#xff0c;在调试的时候没有问题&#xff0c;但是在混淆过后出现了崩溃&#xff1a; 我们知道viewbinding的初始化是ActivityMainBinding.inflate() 而我是通过反射去初始化viewbinding的 很明显&#xff0c;布局所生成的…

viewBinding和@BindView的用法的简单使用

viewBinding 1.module下的build.gradle&#xff0c;在闭包android{ }里面添加 viewBinding {enabled true} 2.使用方法 用视图绑定功能后&#xff0c;系统会为该模块中包含的每个 XML 布局文件生成一个绑定类。这个类的类名是以xml布局文件名去掉下换线后&#xff0c;单词…

BindingNavigator控件

WinForm之中BindingNavigator控件的使用 在微软WinForm中&#xff0c;BindingNavigator控件主要用来绑定数据。可以将一个数据集合与该控件绑定&#xff0c;以进行数据 联动的显示效果。如图下图所示&#xff1a; 那么&#xff0c;下面我们就来用BindingNavigator控件做一下上图…

WinForm控件之【BindingNavigator】【DataSet】【BindingSource】【DataGridView】

基本介绍 数据类控件&#xff0c;数据加载绑定便捷应用相当广泛&#xff0c;具体看例子自行扩展吧&#xff1b; 常设置属性 BindingNavigator--BindingSource&#xff1a;数据来源&#xff0c;绑定后默认项会根据相应的操作按钮执行操作&#xff1b; BindingNavigator--Items&a…

WinForm之中BindingNavigator控件的使用

在微软WinForm中&#xff0c;BindingNavigator控件主要用来绑定数据。可以将一个数据集合与该控件绑定&#xff0c;以进行数据联动的显示效果。如图下图所示&#xff1a; 那么&#xff0c;下面我们就来用BindingNavigator控件做一下上图所示的效果。 分析&#xff1a;该案例以B…

winform控件之BindingNavigator

BindingNavigator控件可以为我们绑定的数据提供一个导航的功能&#xff0c;默认的工具是这个样子的&#xff0c;我们可以根据需求再增加功能 1.BindingNavigator用法 1.1界面布局 界面布局如下 一个BindingNavigator名为bindingNavigator1 一个DataGridView名为DataGridVie…

C#开发之——ToolStrip(10.22)

一 概述 在C# WinForm开发中添加工具栏(ToolStrip)和添加菜单栏类似&#xff0c;在工具箱中将ToolStrip控件直接拖到Windows窗体中即可 <!--more--> 二 ToolStrip操作 从工具箱拖拽ToolStrip控件到Windows窗体后&#xff0c;如下图所示(在添加了ToolStrip控件之后&…

C#winform窗体控件之toolStrip

C#winform窗体控件之toolStrip 在做窗体时我们可能需要一个工具栏&#xff0c;那这时最简单的方法就是添加一个toolStrip控件。 如何完成一个上图的工具栏呢? 首先&#xff0c;需要添加一个toolStrip控件&#xff0c;然后点击控件上的添加按钮&#xff0c;添加你需要的控件&…

C#如何让ToolStrip工具栏按钮分别靠左和靠右对齐分布

ToolStrip工具栏按钮默认靠左对齐&#xff0c;如何让ToolStrip工具栏按钮分别靠左和靠右对齐分布&#xff1f;&#xff01; 第一步&#xff0c;选择要靠右对齐的工具栏上的按钮&#xff0c;属性&#xff0c;设置“Alignment: Right” 即&#xff0c;this.toolStripSysInfoBut…

ToolStrip

&#xfeff;&#xfeff; 效果实现&#xff1a; 1.添加ToolStrip控件 2.点击ToolStrip控件添加button,设置Imagine,对ToolStripButton的Text进行设置,DisplayStyle设置为ImagineAndText即可。

ToolStrip控件中如何添加功能按钮

1&#xff0c;在工具箱中选择ToolStrip控件 2&#xff0c;在属性框&#xff0c;选择item 3,进入该界面&#xff0c;选择添加类型 4&#xff0c;指定选定控件的类型 name:控件的名字&#xff0c;相当于对象名。 text&#xff1a;指定控件中内容限制字段 image&#xff1a;指…

c# ToolStrip控件图片和文字显示

如上图达到这样的效果 首先我们给属性Image和Text分别赋予需要显示的图片和文字 然后设置DisplyStyle属性为ImageAndText&#xff0c;意为同时显示图片和文字 各种设置ImageAlign和TextAlign&#xff0c;调整图片和文字的位置 设置ImageTextRelation属性&#xff0c;获取或…

C# toolstrip按钮的图片不显示

toolstrip按钮的图片不显示 一、设置图片尺寸异常无法正常显示出图片。 以为没正常设置toolStrip尺寸照成图片无法正常显示的效果&#xff0c;如下图&#xff1a; 修改为正常尺寸后可以正常先显示图图片 显示正常 二、按钮没有选择图片显示模式&#xff0c;DisplayStyle:No…

C# ToolStrip 图标大小设置

VS-C 系列&#xff1a;所有相关C文章链接. VS-C# 系列&#xff1a;所有相关C#文章链接. bat 系列&#xff1a;所有相关bat文章链接. Keil 系列&#xff1a;所有相关文章链接 所有内容均以最小系统调试成功&#xff1b;逐步提供低分源码工程下载&#xff01; 保证每行代码都经过…

C# 遍历toolStrip控件

VS-C 系列&#xff1a;所有相关C文章链接. VS-C# 系列&#xff1a;所有相关C#文章链接. bat 系列&#xff1a;所有相关bat文章链接. Keil 系列&#xff1a;所有相关文章链接 所有内容均以最小系统调试成功&#xff1b;逐步提供低分源码工程下载&#xff01; 保证每行代码都经过…

C#toolStrip使用

1、添加toolStrip控件 2、属性栏中将显示方式改为以下属性 3、增加选项卡时选择Button&#xff0c;双击Button就可以编辑事件了