Jetpack系列(四) -- ViewBinding

前言

时间: 23/09/17

AndroidStudio版本: Giraffe 2022.3.1 JDK:17 开发语言: Kotlin

Gradle版本: 8.0 Gradle plugin Version: 8.1.1

概述

ViewBinding,一个用来替代 findViewById 的组件。它简单,好用且常用。在我第一次开发软件(3年前),即使当时使用的是 Java 语言编写的,那时候就已经有 ViewBinding 这个东西了。当时就是在绑定布局的时候,觉得既要定义布局(Layout)视图(View) 变量的类型,又要在生命周期开始后绑定。导致如果页面中的视图太多,就会在 Activity 代码中出现大量的findViewById,数量过多时甚至还会出错,例如类型定义问题,或者更改 xml 中视图类型后代码中类型未更改,导致编译报错问题。ViewBinding可以很舒服,很优雅地解决这些问题。

当然还有一个东西,它是一个开源框架 -- ButterKnife,这个框架原本就是为了解决繁琐的findViewById问题出世的。具体是通过在声明变量时添加注释,来实现视图绑定。具体可以自行查阅或尝试。

ViewBinding的基本使用

ViewBinding的使用可以说是非常的简单,只需要两步。

  • 添加配置

    在build.gradle(app)中添加

    groovy 复制代码
    android {
        ...
        ...
    	buildFeatures {
            viewBinding = true
        }
    }

    注意:不同版本的gradle可能存在配置差异,具体可以查找相关gradle版本的配置方法

  • 直接在 Activity 中使用

    声明一个全局变量,类型为ActivityMainBinding,然后在onCreate()中初始化即可。

    kotlin 复制代码
    class MainActivity : AppCompatActivity() {
        
        lateinit var activityMainBinding: ActivityMainBinding
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            activityMainBinding = ActivityMainBinding.inflate(layoutInflater)
            setContentView(activityMainBinding.root)
            //tvHelloWorld 对应xml布局文件中视图的id,id为tv_hello_world。会自动转成驼峰结构
            activityMainBinding.tvHelloWorld.text = "Hello World!!!"
        }
    }

在 Fragment 中的使用和在 Activity 中几乎时一样的步骤。就是在 inflate 获取生成绑定类的实例时,需要多传两个参数。在onCreateView中

kotlin 复制代码
	private var fragmentMainBinding: ActivityMainBinding? = null

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        fragmentMainBinding = ActivityMainBinding.inflate(inflater, container, false)
        return fragmentMainBinding?.root
    }
//我这里没有修改布局文件名称,所以类型仍然是ActivityMainBinding
//另外需要注意一点,由于onCreateView中参数container是可为空的参数,所以定义fragmentMainBinding时,最好还是定义成可为空的形式

ViewBinding 使用优化

从上面可以看出,使用 ViewBinding 真的很简单,也很方便。如果你修改了 layout 中 View 的类型,只要 id 没变,你甚至不需要修改任何代码。这也是为什么推荐使用binding的原因。

从上面也看出,ViewBinding的使用其实是固定了格式的。并且所有我们的 Activity 都可以使用。如果你有安卓或者说有编程的基础,可能就会联想到我们在编写代码时,会将一些重复性的逻辑代码写道一个函数(方法)中,我们在需要执行这些逻辑时,只需要调用这个方法即可。

同理 ------ 是不是可以通过什么方法或者手段让这个固定的操作也只需要调用而不需要次次都编写代码呢?

答案当然是肯定的,暂且不提用方法实现,通常我们在编写app程序时,会编写一个BaseActivity,用来执行每个或大部分Activity都会执行的固定逻辑代码。

废话不多说,直接上代码

kotlin 复制代码
//BaseActivity
abstract class BaseActivity<T : ViewBinding> : AppCompatActivity() {
    lateinit var mViewBinding: T
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mViewBinding = getViewBinding()
        setContentView(mViewBinding.root)
    }
    abstract fun getViewBinding(): T
}

//MainActivity
class MainActivity : BaseActivity<ActivityMainBinding>() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mViewBinding.tvHelloWorld.text = "Hello World!!!"
    }

    override fun getViewBinding(): ActivityMainBinding {
        return ActivityMainBinding.inflate(layoutInflater)
    }
}

可以看出,我们在BaseActivity中调用了抽象方法getViewBinding实现了setContentView,这个抽象方法我们需要在MainActivity中实现。这样就可以直接在MainActivity使用mViewBinding来引用 视图 或者 布局 了。当然,也可以将mViewBinding设置成protected,这样会更安全些。

在Fragment中的使用优化也是如此,就不做过多赘述。

总结

本文较为详细地介绍了 ViewBinding 组件的使用。讲述了基础使用和使用优化,对于不同的使用场景也有提及。相对于前面三篇内容来说,这篇还是比较简单的,但是不代表ViewBinding它不重要或不常用。简单反而说明了它对于使用者有巨大的作用。后续会讲另一个绑定相关的组件 DataBinding ,它比 ViewBinding 难,并且包含了ViewBinding 的功能。

相关推荐
alexhilton16 小时前
端侧RAG实战指南
android·kotlin·android jetpack
Kapaseker1 天前
2026年,我们还该不该学编程?
android·kotlin
Kapaseker2 天前
一杯美式搞懂 Any、Unit、Nothing
android·kotlin
BoomHe3 天前
Now in Android 架构模式全面分析
android·android jetpack
Kapaseker3 天前
一杯美式搞定 Kotlin 空安全
android·kotlin
FunnySaltyFish4 天前
什么?Compose 把 GapBuffer 换成了 LinkBuffer?
算法·kotlin·android jetpack
Kapaseker4 天前
Compose 进阶—巧用 GraphicsLayer
android·kotlin
Kapaseker5 天前
实战 Compose 中的 IntrinsicSize
android·kotlin
黄林晴5 天前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
A0微声z7 天前
Kotlin Multiplatform (KMP) 中使用 Protobuf
kotlin