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

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

一、前言

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

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

二、环境的配置

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

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

    <LinearLayout
            ...
            tools:viewBindingIgnore="true" >
            ...
    </LinearLayout>    
    AI 代码解读

三、view Binding 基本用法

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

//布局名字
fragment_name.xml
//生成类名
FragmentNameBinding
AI 代码解读

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

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

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)
        ...
    }
AI 代码解读

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
}
AI 代码解读

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
}
AI 代码解读

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
AI 代码解读

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

四、总结

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

目录
打赏
0
0
0
0
25
分享
相关文章
重构旧代码的秘诀:用设计模式 - 适配器模式(Adapter)给Java项目带来新生
【4月更文挑战第7天】适配器模式是解决接口不兼容问题的结构型设计模式,通过引入适配器类实现目标接口并持有不兼容类引用,实现旧代码与新接口的协作。适用于处理兼容性问题、整合遗留代码和集成第三方库。应用时,识别不兼容接口,创建适配器类转换方法调用,然后替换原有引用。注意保持适配器简单、使用组合和考虑扩展性。过度使用可能导致系统复杂和维护成本增加,应谨慎使用。
133 4
Flutter相关痛点解决问题之iBox模块的源码结构的设计如何解决
Flutter相关痛点解决问题之iBox模块的源码结构的设计如何解决
代码的应用重构问题之BaseActivity类的主要功能问题如何解决
代码的应用重构问题之BaseActivity类的主要功能问题如何解决
《移动互联网技术》第十一章 Android应用工程案例: 掌握Android系统的需求分析和设计以及 Android项目的程序测试和版本管理方法
《移动互联网技术》第十一章 Android应用工程案例: 掌握Android系统的需求分析和设计以及 Android项目的程序测试和版本管理方法
164 0
前端学习笔记202305学习笔记第二十三天-重构和代码迁移1
前端学习笔记202305学习笔记第二十三天-重构和代码迁移1
66 0
【Java设计模式 规范与重构】 一 重构的目的、内容、时机、方法
【Java设计模式 规范与重构】 一 重构的目的、内容、时机、方法
221 0
前端hook项目重构笔记1-重构之裁剪上传功能
前端hook项目重构笔记1-重构之裁剪上传功能
88 0
前端hook项目重构笔记1-重构之裁剪上传功能
前端hook项目重构笔记4-重构之裁剪上传功能
前端hook项目重构笔记4-重构之裁剪上传功能
101 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等