viewBinding的使用记一次重构项目的过程

简介: 最近放寒假了,终于有空做项目了,想着把之前的一些项目重构一下,碰巧重构到 view Binding 这块,之前都是用 kotlin 的那个扩展,其实刚开始做项目的时候这个就已经废弃了,由于当时自己有点懒,没去学习这个新的代替方案,所以就成为一个历史遗留的问题,参考官方文档

一、前言

最近放寒假了,终于有空做项目了,想着把之前的一些项目重构一下,碰巧重构到 view Binding 这块,之前都是用 kotlin 的那个扩展,其实刚开始做项目的时候这个就已经废弃了,由于当时自己有点懒,没去学习这个新的代替方案,所以就成为一个历史遗留的问题,参考官方文档

view Binding 官方文档,这里只是针对目前使用的几个场景进行重构,其他未涉及的场景可以同理得出。

二、环境的配置

  • Android Studio 的版本至少需要3.6及以上
  • 在build.gradle 配置文件下添加以下语句,不过现在的版本貌似是默认启用view Binding

    android {
            ...
            viewBinding {
                enabled = true
            }
    }
  • 由于绑定类是创建布局文件即生成的,故想要忽略某个布局需要在根布局添加以下内容

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

三、view Binding 基本用法

首先利用布局绑定的类进行创建一个对象,并对其进行初始化,然后就获得一个viewBinding的对象,用此对象进行获取布局所对应的view以及布局下的相关控件,首先说明一下自动生成的命名规则,自动去掉_空格等非字母字符,其他单词采取首字母大写的命名法则最后加个Binding结尾,举个例子

//布局名字
fragment_name.xml
//生成类名
FragmentNameBinding

binding自动调用布局里面的id也发生了一些变化,变成驼峰的命名法,同样会忽略掉非字母字符,举个例子

//布局里面某个控件的id
android:id="@+id/item_name"
//生成的变量名
FragmentNameBinding.itemName

1. Activity 中的用法

首先创建一个延迟初始化的binding变量,然后在创建activity时进行初始化,设置当前的view,只需用binding.root即可获取

    private lateinit var binding:FragmentNameBinding
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = FragmentNameBinding.inflate(layoutInflater)
        setContentView(binding.root)
        ...
    }

2. Fragment 中的用法

这个和Activity差不多,就是初始化不一样,这边采用一种比较安全的策略使得binding在fragment内部不能被修改,binding的get方法为_binding的,外部可以改变binding的值,内部不行

private var _binding: ResultProfileBinding? = null

//断言binding非空
private val binding get() = _binding!!
override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    _binding = ResultProfileBinding.inflate(inflater, container, false)
    return binding.root
}

3. Adapter 中的用法

这个稍微麻烦一点,不过原理还是一样的,下面这个例子即可说明,针对那些使用findViewById进行了一些优化,这里涉及item的复用,注意变量的作用域范围,考虑binding的声明位置

class TestAdapter(private val fragment:Fragment,private val testList: List<Test>):RecyclerView.Adapter<TestAdapter.ViewHolder>(){
    
    //对于holder参数进行了改造
    inner class ViewHolder(binding: TestItemBinding):RecyclerView.ViewHolder(binding.root){
        val fundName = binding.name
    }

    
    //在这里进行binding的初始化,这里对bingding的赋值和fragment类似
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder{
        val binding = TestItemBinding.inflate(LayoutInflater.from(parent.context),parent,false)
        binding.root.setOnClickListener {
            val name = binding.name
        }
        return ViewHolder(binding)
    }

    //这里其实基本不需要改动,但却是用binding的用法进行的
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.name = "test"
    }

    override fun getItemCount() = testList.size
}

4.使用include包含布局的嵌套布局

这个刚开始也有点懵,官方文档好像没写,后来想想,包含布局不是也可以当成一个控件使用,所以最后采用在包含控件前添加id实现了调用

<ScrollView
   ...
    <LinearLayout
        ...
        <include
            android:id="@+id/basic"
            layout="@layout/basic"/>
    </LinearLayout>
    ...
</ScrollView>
//如果上述布局名字是fragment_basic.xml,则采用下述方式获得layout的binding
val basic = FragmentBasicBinding.inflate(layoutInflater)
basic.basic
//这个即为layout basic的binding

当然还有更简单的想法,直接再定义一个layout所对应的binding,如果实在不会获取的话,跟上面几种情况类似就不过多说明了

四、总结

总体来讲这次重构是比较成功的,以前使用kotlin扩展虽然方便但是还是比较容易出错,尤其是不同布局采用相同的id名时经常弄错,用了view binding之后就不需要担心这个了,与视图相绑定,安全性大大提高,同时也简化了传统的获取id的方法,是一次比较愉快的重构。

目录
相关文章
|
JavaScript
cnpm安装淘宝镜像
cnpm安装淘宝镜像
Threejs实现模拟管道液体流动
Threejs实现模拟管道液体流动
3453 0
Threejs实现模拟管道液体流动
|
安全 Java Android开发
SpringBoot 代码混淆方案 ProGuard
在软件开发中,代码混淆是故意创建人类难以理解的源代码或机器代码的行为。代码混淆处理修改了可部署的文件,因此黑客很难从中读取信息,但仍然保持完整的功能。这最初是为 android 平台引入的。它现在能够支持 SpringBoot 2。
|
存储 容器
vue3【实战】来回拖拽放置图片
vue3【实战】来回拖拽放置图片
288 2
|
人工智能 JavaScript 算法
Vue 报错 error:0308010C:digital envelope routines::unsupported
Vue 报错 error:0308010C:digital envelope routines::unsupported
|
前端开发 JavaScript 测试技术
深入探索自动化测试框架:Selenium与Appium的对比分析
【4月更文挑战第29天】 在快速迭代的软件发展环境中,自动化测试已成为确保软件质量和加速产品上市的关键步骤。本文将重点探讨两种广泛使用的自动化测试框架——Selenium和Appium,通过对比它们的核心特性、适用场景及执行效率,为软件开发和测试团队提供选择指南。文章不仅分析了各自的技术架构和脚本语言支持,还讨论了它们在处理Web应用和移动应用测试时的优缺点,旨在帮助读者根据项目需求做出更加明智的选择。
1003 0
|
Android开发 C++
【Android NDK 开发】在 C 代码中获取 Android 系统信息 ( NDK 项目创建 | NDK 配置 | 获取 Android 系统版本号 )(二)
【Android NDK 开发】在 C 代码中获取 Android 系统信息 ( NDK 项目创建 | NDK 配置 | 获取 Android 系统版本号 )(二)
1983 0
【Android NDK 开发】在 C 代码中获取 Android 系统信息 ( NDK 项目创建 | NDK 配置 | 获取 Android 系统版本号 )(二)
|
存储 编解码 算法
音视频编程ffmepg中的关键术语与概念:深度解析与实践(二)
音视频编程ffmepg中的关键术语与概念:深度解析与实践
564 0
|
前端开发 Android开发
React Native 离线包/图片资源
1). 打包 进入项目根目录(如图1,anubis为项目名)执行命令 react-native bundle --platform android --dev false --entry-file index.
1841 0
|
Ubuntu
ubuntu源码安装flex和bison
ubuntu源码安装flex和bison
1210 0