網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
Google 在 Android Studio 3.6 Canary 11
及更高版本中提供了一個(gè) viewBinding
的開關(guān),可以開啟視圖綁定功能,以此來替代 findViewById
。
viewBinding功能可按模塊啟用。要在某個(gè)模塊中啟用viewBinding,請(qǐng)將 viewBinding
元素添加到其 build.gradle
文件中,如下例所示:
android {
? ? ...
? ? viewBinding {
? ? ? ? enabled = true
? ? }
}
如果您希望在生成綁定類時(shí)忽略某個(gè)布局文件,請(qǐng)將 tools:viewBindingIgnore="true"
屬性添加到相應(yīng)布局文件的根視圖中:
<LinearLayout ... tools:viewBindingIgnore="true" > ... </LinearLayout>
為某個(gè)模塊啟用視圖綁定功能后,系統(tǒng)會(huì)為該模塊中包含的每個(gè) XML 布局文件生成一個(gè)綁定類。每個(gè)綁定類均包含對(duì)根View以及具有 ID 的所有View的引用。系統(tǒng)會(huì)通過以下方式生成綁定類的名稱:將 XML 文件的名稱轉(zhuǎn)換為駝峰式大小寫,并在末尾添加“Binding”。
例如,假設(shè)某個(gè)布局文件的名稱為 result_profile.xml
:
<LinearLayout ... > <TextView android:id="@+id/name" /> <ImageView android:cropToPadding="true" /> <Button android:id="@+id/button" android:background="@drawable/rounded_button" /> </LinearLayout>
所生成的綁定類的名稱就為 ResultProfileBinding
。此類具有兩個(gè)字段:一個(gè)是名為 name
的 TextView
,另一個(gè)是名為 button
的 Button
。該布局中的 ImageView
沒有 ID,因此綁定類中不存在對(duì)它的引用。
每個(gè)綁定類還包含一個(gè) getRoot()
方法,用于為相應(yīng)布局文件的根View提供直接引用。在此示例中,ResultProfileBinding
類中的 getRoot()
方法會(huì)返回 LinearLayout
根視圖。
在 Activity 中使用 viewBinding
如需設(shè)置綁定類的實(shí)例以供 Activity 使用,請(qǐng)?jiān)?Activity 的 onCreate()
方法中執(zhí)行以下步驟:
- 調(diào)用生成的綁定類中包含的靜態(tài)
inflate()
方法。此操作會(huì)創(chuàng)建該綁定類的實(shí)例以供 Activity 使用。 - 通過調(diào)用
getRoot()
方法或使用 Kotlin 屬性語(yǔ)法獲取對(duì)根View的引用。 - 將根視圖傳遞到
setContentView()
,使其成為屏幕上的活動(dòng)View。
private lateinit var binding: ResultProfileBinding override fun onCreate(savedInstanceState: Bundle) { super.onCreate(savedInstanceState) binding = ResultProfileBinding.inflate(layoutInflater) val view = binding.root setContentView(view) }
然后即可使用該綁定類的實(shí)例來引用任何View控件:
binding.name.text = viewModel.name binding.button.setOnClickListener { viewModel.userClicked() }
在Fragment中使用viewBinding
如需設(shè)置綁定類的實(shí)例以供 Fragment 使用,請(qǐng)?jiān)?Fragment 的 onCreateView()
方法中執(zhí)行以下步驟:
- 調(diào)用生成的綁定類中包含的靜態(tài)
inflate()
方法。此操作會(huì)創(chuàng)建該綁定類的實(shí)例以供 Fragment 使用。 - 通過調(diào)用
getRoot()
方法或使用 Kotlin 屬性語(yǔ)法獲取對(duì)根View的引用。 - 從
onCreateView()
方法返回根View,使其成為屏幕上的活動(dòng)View。
private var _binding: ResultProfileBinding? = null // This property is only valid between onCreateView and onDestroyView. private val binding get() = _binding!! override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { _binding = ResultProfileBinding.inflate(inflater, container, false) val view = binding.root return view } override fun onDestroyView() { super.onDestroyView() _binding = null }
然后即可使用該綁定類的實(shí)例來引用任何View控件:
binding.name.text = viewModel.name binding.button.setOnClickListener { viewModel.userClicked() }
注意:inflate()
方法會(huì)要求傳入LayoutInflater
對(duì)象。如果布局已經(jīng)inflated
,則可以調(diào)用綁定類的靜態(tài) bind()
方法。 例如:
/** * View Binding example with a fragment that uses the alternate constructor for inflation and * [onViewCreated] for binding. */ class BindFragment : Fragment(R.layout.fragment_blank) { // Scoped to the lifecycle of the fragment's view (between onCreateView and onDestroyView) private var fragmentBlankBinding: FragmentBlankBinding? = null override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) val binding = FragmentBlankBinding.bind(view) fragmentBlankBinding = binding binding.textViewFragment.text = getString(string.hello_from_vb_bindfragment) } override fun onDestroyView() { // Consider not storing the binding instance in a field, if not needed. fragmentBlankBinding = null super.onDestroyView() } }
注意:Fragment 的存在時(shí)間比其視圖長(zhǎng)。請(qǐng)務(wù)必在 Fragment 的 onDestroyView()
方法中清除對(duì)綁定類實(shí)例的所有引用。
與findViewById的區(qū)別
與使用 findViewById
相比,viewBinding
具有一些很顯著的優(yōu)點(diǎn):
- Null 安全:由于viewBinding會(huì)創(chuàng)建對(duì)View的直接引用,因此不存在因View ID 無(wú)效而引發(fā)空指針異常的風(fēng)險(xiǎn)。此外,如果View僅出現(xiàn)在布局的某些配置中,則綁定類中包含其引用的字段會(huì)使用
@Nullable
標(biāo)記。 - 類型安全:每個(gè)綁定類中的字段均具有與它們?cè)?XML 文件中引用的View相匹配的類型。這意味著不存在發(fā)生類轉(zhuǎn)換異常的風(fēng)險(xiǎn)。
這些差異意味著布局和代碼之間的不兼容將會(huì)導(dǎo)致構(gòu)建在編譯時(shí)(而非運(yùn)行時(shí))失敗。
與dataBinding的對(duì)比
viewBinding和dataBinding 均會(huì)生成可用于直接引用視圖的綁定類。但是,viewBinding旨在處理更簡(jiǎn)單的用例,與dataBinding 相比,具有以下優(yōu)勢(shì):
- 更快的編譯速度:viewBinding不需要處理注解,因此編譯時(shí)間更短。
- 易于使用:viewBinding不需要特別標(biāo)記的 XML 布局文件,因此在應(yīng)用中采用速度更快。在模塊中啟用viewBinding后,它會(huì)自動(dòng)應(yīng)用于該模塊的所有布局。
反過來,與 dataBinding 相比,viewBinding 也具有以下限制:
- viewBinding不支持布局變量或布局表達(dá)式,因此不能用于直接在 XML 布局文件中聲明動(dòng)態(tài)界面內(nèi)容。
- viewBinding不支持雙向數(shù)據(jù)綁定。
替代 KAE
viewBinding 還有一個(gè)重要作用是替代以前的 Kotlin Android Extensions,在之前的kotlin版本中提供了一個(gè)針對(duì)android的擴(kuò)展插件,它可以允許我們直接用布局文件中的 view id 來訪問 view,也無(wú)需寫 findViewById。
但是由于 KAE 存在一些潛在的 bug (例如可以訪問到不屬于當(dāng)前Activity布局的view id造成空指針異常等), 從 Kotlin 1.7 開始,KAE被正式移除了。
那么 viewBinding 的出現(xiàn)也是為了彌補(bǔ)之前 KAE 的功能和缺陷。
最后,viewBinding 只是針對(duì)傳統(tǒng) View 體系的開發(fā),在進(jìn)入 Jetpack Compose 的世界以后,這項(xiàng)功能就基本無(wú)用武之地了。
原文鏈接:https://blog.csdn.net/lyabc123456/article/details/128759579
相關(guān)推薦
- 2023-05-06 Python正則表達(dá)式中g(shù)roup與groups的用法詳解_python
- 2023-01-19 使用python檢查值是否已經(jīng)存在于字典列表中_python
- 2023-10-16 清理linux日志
- 2023-01-23 redis實(shí)現(xiàn)多級(jí)緩存同步方案詳解_Redis
- 2023-01-27 如何使用Redux?Toolkit簡(jiǎn)化Redux_React
- 2022-05-03 基于docker部署skywalking實(shí)現(xiàn)全鏈路監(jiān)控功能_docker
- 2022-09-12 .Net6集成IdentityServer4?+AspNetCore?Identity讀取數(shù)據(jù)表用戶
- 2022-08-17 jQuery實(shí)現(xiàn)購(gòu)物車_jquery
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支