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 的功能。

相关推荐
webbin1 小时前
Compose @Immutable注解
android·android jetpack
webbin2 小时前
Compose 副作用
android·android jetpack
纳于大麓4 小时前
Kotlin基础语法五
android·开发语言·kotlin
移动开发者1号4 小时前
嵌套滚动交互处理总结
android·kotlin
移动开发者1号4 小时前
Android工程中FTP加密传输与非加密传输的深度解析
android·java·kotlin
yzpyzp18 小时前
Kotlin的MutableList和ArrayList区别
android·kotlin
帅次20 小时前
Flutter Container 组件详解
android·flutter·ios·小程序·kotlin·iphone·xcode
帅次1 天前
Flutter setState() 状态管理详细使用指南
android·flutter·ios·小程序·kotlin·android studio·iphone
Wgllss1 天前
大型异步下载器:基于kotlin+Compose+协程+Flow+Channel实现多文件异步同时分片断点续传下载
android·架构·android jetpack
_一条咸鱼_1 天前
Android Runtime JIT编译器核心技术原理分析(36)
android·面试·android jetpack