【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
英文地址,請注明出處:http://en.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;一、設…