【Android】ViewBinding(视图绑定)

一、什么是ViewBinding

ViewBinding是Android Studio 3.6推出的新特性,旨在替代findViewById(内部实现还是使用findViewById)。通过ViewBinding,可以更轻松地编写可与视图交互的代码。在模块中启用ViewBinding之后,系统会为该模块中的每个 XML 布局文件生成一个绑定类。绑定类的实例包含对在相应布局中具有 ID 的所有视图的直接引用。

二、ViewBinding的优势

与使用findViewById相比,ViewBinding有明显的优势:

1.类型安全:ViewBinding 生成的属性类型和布局中的View类型是一致的,不需要进行类型转换,相对于findViewById有类型安全性。

//findViewById需要类型转换
TextView textView=(TextView) findViewById(R.id.text_view);
//ViewBinding不需要类型转换
binding.textView.setText("Hello");

2.减少空指针异常:ViewBinding可以直接访问绑定类中的视图,因此不存在因 view ID 找不到而引发空指针异常的风险。

3.代码更简洁:使用ViewBinding只需要获取一次实例,就可以实现对所有控件的调用,相对于findViewById不用多次获取实例,代码更简洁。

三、ViewBinding的使用

1.使用前提

1.1添加依赖

在 app目录下的的 build.gradle 文件中,添加如下代码:

android {...buildFeatures {viewBinding true}
}

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

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

添加后点击Sync Now进行同步工程,完成配置 

1.2生成绑定类

完成第一步后点击编译后自动生成绑定类

位置如图所示:

 绑定类的命名规则:

将xml文件名转化为驼峰命名法,即去掉下划线并将每个单词首字母大写,例如:

布局文件名:activity_main.xml

生成绑定类名:ActivityMainBinding

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

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

2.使用ViewBinding 

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

2.1在Activity中使用ViewBinding

在布局文件中,我们设定了两个控件TextView和Button,不需要有任何修改

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/main"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:id="@+id/text_view"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="136dp"android:text="TextView"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintTop_toTopOf="parent" /><Buttonandroid:id="@+id/button1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="92dp"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintTop_toBottomOf="@+id/text_view" /></androidx.constraintlayout.widget.ConstraintLayout>
  • 如果使用findViewById,我们需要多次获取实例:
public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);TextView textView=(TextView) findViewById(R.id.text_view);Button button1=(Button) findViewById(R.id.button1);}}
  • 如果使用ViewBinding:
public class MainActivity extends AppCompatActivity {protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);ActivityMainBinding binding=ActivityMainBinding.inflate(getLayoutInflater());setContentView(binding.getRoot());binding.textView.setText("Hello");binding.button1.setOnClickListener(v -> {Toast.makeText(MainActivity.this,"Button1",Toast.LENGTH_SHORT).show();});}}

可以发现只用获取一次实例就可以操作所有控件

1.使用inflate方法:inflate是ViewBinding提供的静态方法,用于将布局文件解析成对应的视图对象。getLayoutInflater用于获取LayoutInflater对象,该对象可以将XML文件转换为视图。

2.创建绑定对象:会创建一个ActivityMainBinding类绑定对象。这个对象包含了对activity_main.xml布局文件中所有视图的引用,可以通过这个对象直接访问和操作视图。

2.2在Adapter中使用ViewBinding 

在使用RecyclerView中,我们在自定义适配器中也有许多运用到findViewById的地方,可以用ViewBinding替代。

  • 如果使用findViewById
package com.example.viewbinding;import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;import androidx.recyclerview.widget.RecyclerView;import java.util.List;public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {private List<String> mFruitList;public FruitAdapter(List<String> fruits){mFruitList=fruits;}public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view,parent,false);ViewHolder holder=new ViewHolder(view);return holder;}public void onBindViewHolder(ViewHolder holder,int position){String fruitname=mFruitList.get(position);holder.textView.setText(fruitname);}public int getItemCount(){return mFruitList.size();}static class ViewHolder extends RecyclerView.ViewHolder {TextView textView;public ViewHolder(View view) {super(view);textView = (TextView) view.findViewById(R.id.fruit_name);}}
}
  • 如果使用ViewBinding
    public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {private List<String> mFruitList;private LayoutInflater inflater;public FruitAdapter(Activity activity,List<String> fruits){mFruitList=fruits;inflater=LayoutInflater.from(activity);}public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){RecyclerViewBinding binding = RecyclerViewBinding.inflate(inflater, parent, false);ViewHolder holder=new ViewHolder(binding);return holder;}public void onBindViewHolder(ViewHolder holder,int position){String fruitname=mFruitList.get(position);holder.textView.setText(fruitname);}public int getItemCount(){return mFruitList.size();}static class ViewHolder extends RecyclerView.ViewHolder {TextView textView;private RecyclerViewBinding binding;public ViewHolder(RecyclerViewBinding binding) {super(binding.getRoot());textView = binding.fruitName;}}
    }

    2.3在布局中嵌套include标签

如果布局中存在嵌套,比如使用 include 标签引用了另一个布局,这时就没法直接用XXXbinding对象去引用嵌套布局里的id了。

解决方法:

  1. 为include标签添加id;
  2. 使用 binding 访问到 include 节点,再访问到 include节点内部的其他控件。

再举例说明一下,在activity_main.xml中我们用include标签引用了一个布局 title_bar.xml,同时为它添加了id

<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/main"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><includeandroid:id="@+id/include_title_bar"layout="@layout/title_bar" /><TextViewandroid:id="@+id/text_view"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="136dp"android:text="TextView"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintTop_toTopOf="parent" /><Buttonandroid:id="@+id/button1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="92dp"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintTop_toBottomOf="@+id/text_view" /></androidx.constraintlayout.widget.ConstraintLayout>

 title_bar.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:id="@+id/text_hello"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="hello"/></LinearLayout>

在Activity中访问:

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);ActivityMainBinding binding=ActivityMainBinding.inflate(getLayoutInflater());setContentView(binding.getRoot());binding.textView.setText("Hello");binding.includeTitleBar.textHello.setText("Hello");binding.button1.setOnClickListener(v -> {Toast.makeText(MainActivity.this,"Button1",Toast.LENGTH_SHORT).show();});}
}

这样我们就实现了使用ViewBinding完成布局嵌套。

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

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

相关文章

泛型与类型安全深度解析及响应式API实战

一、泛型通配符&#xff1a;灵活与安全的平衡术 在Java动物收容所系统中&#xff0c;我们常需要处理不同动物类型的集合。通过泛型通配符&#xff0c;可以构建更灵活的API&#xff1a; class Shelter<T extends Animal> {private List<T> animals new ArrayList&l…

Cookie 与 Session概述

在 Web 开发中&#xff0c;会话跟踪是一个核心问题。HTTP 协议是无状态的&#xff0c;这意味着服务器无法直接记住客户端的状态。而 Cookie 和 Session 技术的出现&#xff0c;正是为了解决这一难题。一、Cookie概述Cookie&#xff0c;翻译成中文是小甜点、小饼干的意思。在 HT…

阿里云alicloud liunux3-安装docker

你这个错误&#xff1a;Curl error (35): SSL connect error for https://download.docker.com/linux/centos/8/x86_64/stable/... Error: Failed to download metadata for repo docker-ce-stable: Yum repo downloading error说明你的机器访问 download.docker.com 的 HTTPS …

【世纪龙科技】汽车故障诊断与排除仿真教学软件

在汽车产业智能化、电动化转型加速的今天&#xff0c;汽车维修行业对技术人才的要求已从传统经验型向“理论实践数字化”复合型转变。然而&#xff0c;实车实训成本高、安全隐患大、教学场景受限等问题&#xff0c;始终制约着职业教育的高质量发展。江苏世纪龙科技有限公司立足…

柴油机活塞cad【4张】三维图+设计说明书

1015柴油机活塞结构设计及温度场分析 摘 要 随着科研的进步&#xff0c;内燃机技术得到了快速的发展&#xff0c;低排放高效率的内燃机的发展成为内燃机发展的主要趋势&#xff0c;活塞作为内燃机的主要组成部件&#xff0c;在内燃机中扮演着至关重要的作用。活塞在内燃机中始终…

雪豹大模型驱动效率革命 华鼎冷链科技重构餐饮供应链神经网络

当餐饮行业的开店率高达67.5%、闭店率达61.2%时&#xff0c;供应链该如何进行革新与升级&#xff1f; 在郑州盛大启幕的第三届中国火锅烧烤领潮峰会上&#xff0c;华鼎冷链科技CEO王君以“AI驱动智慧供应链赋能餐饮行业新升级”为主题分享时称&#xff0c;当前餐饮行业高闭店率…

汽车功能安全 -- TC3xx外部看门狗

之前聊过TC3xx SMU关于内部看门狗&#xff08;CPU Watchdog 和Safety Watchdog&#xff09;Alarm的处理方法。 汽车功能安全--TC3xx SMU之看门狗alarm处理 在里面我们提到了这些Alarm关联的功能安全机制&#xff1a; SM[HW]:SCU:ENDINIT_WATCHDOG SM[HW]:SCU:SAFETY_WATCHD…

如何为“地方升学导向型”语校建模?Prompt 框架下的宇都宫日建工科专门学校解析(7 / 500)

如何为“地方升学导向型”语校建模&#xff1f;Prompt 框架下的宇都宫日建工科专门学校解析&#xff08;7 / 500&#xff09; 系列说明 500 所日本语言学校结构化建模实战&#xff0c;第 7 篇。每篇拆解 1 所学校在 Prompt-QA 系统中的建模策略&#xff0c;分享工程经验&#x…

Flutter 入门指南:从基础到实战

介绍 Flutter Flutter 是 Google 开发的开源移动应用软件开发工具包&#xff08;SDK&#xff09;&#xff0c;用于快速在 iOS 和 Android 上构建高质量的原生界面。Flutter 的一大特点是其跨平台功能&#xff0c;让开发者能够使用同一套代码基础为两个平台构建应用。这一点通过…

八字命理:枭印夺食的形成原理与解决办法

枭印夺食(|)含义:原局食神伤官为喜用&#xff0c;印为忌正印/偏印克制了食神/伤官&#xff0c;克制形式可以是盖头/截脚/同在天干或者地支时相克(2)表现症状:emo、敏感、好面子、不敢开口说话、被环境压制(3)症状剖析:印为忌&#xff1d;他人即地狱&#xff0c;不论正印(吉神)还…

数组和对象的深拷贝和浅拷贝的方法

数组和对象的深拷贝、浅拷贝方法有所不同&#xff0c;以下是常见的实现方式&#xff1a;一、浅拷贝方法&#xff08;数组和对象通用/专用&#xff09;浅拷贝只复制表层数据&#xff0c;嵌套的引用类型仍共享内存。1. 数组的浅拷贝- 扩展运算符&#xff08;...&#xff09;&…

【RK3576】【Android14】开发板概述

获取更多相关的【RK3576】【Android14】驱动开发&#xff0c;可收藏系列博文&#xff0c;持续更新中&#xff1a; 【RK3576】Android 14 驱动开发实战指南 1. 引言 RK3576处理器简介&#xff1a; RK3576 是一颗高性能、低功耗的应用处理器芯片&#xff0c;专为ARM PC、边缘计算…

凸优化课程学习笔记(一)

凸优化课程学习笔记(一) 课程:B站清华大学陈剑博士《凸优化基础理论与应用》 优化理论概述 1. 优化序论 定义:凸优化是一门应用极为广泛的学科,主要研究如何对决策问题进行最优选择,探讨最优解的性质,寻找高效的计算方法,并分析这些方法的理论基础与实际应用表现。…

(四)OpenCV——特征点检测与匹配

前言 特征点检测与匹配是计算机视觉中的基础技术&#xff0c;广泛应用于图像拼接、物体识别、三维重建、运动跟踪等领域。OpenCV 提供了多种特征检测与匹配算法的实现。 特征点检测与匹配是计算机视觉中的核心技术&#xff0c;广泛应用于多个领域。以下是其主要应用场景&…

if (a == 1 a == 2 a == 3)返回true的问题思考

引文&#xff1a; 无意中看到了这样的非常规逻辑&#xff0c;在想前后端应该都可以实现&#xff0c;a 是变量&#xff0c;或者操作a时触发了值得改变。 意义&#xff1a; 该问题让我们知道了一切规则都是可以被打破的&#xff0c;世界上的规则都是为了解释某种现象设计的。 题目…

MySQL的索引操作及底层结构浅析

一.索引提高数据库的性能&#xff0c;索引是物美价廉的东西了。不用加内存&#xff0c;不用改程序&#xff0c;不用调sql&#xff0c;只要执行正确的 create index &#xff0c;查询速度就可能提高成百上千倍。但是天下没有免费的午餐&#xff0c;查询速度的提高是以插入、更新…

stm32f4 dma的一些问题

文章目录前言一、使用开发板烧录dma代码不生效问题二、一个工程同时使用uart2、uart3借助dma来传递1.并行。2.DMA "同时工作"的本质3.总线访问的具体含义4.实际效果5.最佳实践5.1 总线传输机制&#xff1a;6.DMA传输中断的问题总结前言 记录一些使用stm32f4 dma过程…

登录功能实现深度解析:从会话管理到安全校验全流程指南

登录功能实现深度解析&#xff1a;从会话管理到安全校验全流程指南大家好&#xff0c;我是凯哥Java本文标签&#xff1a;登录验证流程、过滤器与拦截器、安全防护措施简介本文深入探讨了从登录功能实现到会话管理和安全校验的全流程&#xff0c;包括参数校验、身份验证、令牌生…

2023 年 5 月青少年软编等考 C 语言六级真题解析

目录 T1. 字符串插入 思路分析 T2. 机器翻译 思路分析 T3. 栈基本操作 思路分析 T4. 双端队列 思路分析 T1. 字符串插入 题目链接:SOJ D1138 有两个字符串 s t r str str 和 s u b s t r substr substr, s t r str str 的字符个数不超过 10 10 10, s u b s t r substr …

Redux架构解析:状态管理的核心原理

Redux 作为 JavaScript 应用的状态管理库&#xff0c;其技术架构与核心原理围绕​​可预测的状态管理​​设计&#xff0c;通过严格的单向数据流和函数式编程理念实现复杂应用的状态控制。以下从设计理念、核心架构、工作流程、源码实现等角度进行系统性剖析&#xff1a;一、设…