小工具知识网

当前位置: 首页 > 行业知识 > Android解放双手的利器之ViewBinding

行业知识

Android解放双手的利器之ViewBinding

2026-11-10 20:43:09 来源:互联网转载

文章目录

    • 1. 背景
    • 2. ViewBinding是什么
    • 3. 开启ViewBinding功能
    • 4. 生成绑定类
    • 5. 使用ViewBinding
      • 5.1Activity 中使用
      • 5.2 Fragment 中使用
      • 5.3 ViewHolder 中使用
      • 6. ViewBinding的优点
      • 7. 与 dataBinding 对比

        1. 背景

        写代码最繁琐的是什么?重复的机械操作。我们刚接触Android开发时最常写的操作肯定少不了findViewById 的身影。如果页面简单,负担还好,多写几行而已,但如果界面中存在几十上个View呢?再或者,重复的做一件枯燥的事几百次呢?这时候就会敲代码敲到手抽筋,有点生无可恋了吧。

        2. ViewBinding是什么

        这时候你的救星它来了!解放你的双手,效率提升十倍!它就是 ViewBinding !

        ViewBinding ,顾名思义是“视图绑定”。它可以自动为 XML 布局文件生成一个绑定类,通过这个绑定类,你可以直接拿到布局中的View,再也不用 findViewById 的一个个去找了。

        ViewBinding 是AndroidStudio3.6以后就支持的功能,现在大家的Android Studio版本应该都是202x.x.x这种新的年月日版本了吧。Android Studio4.2.2之后就采用这种新版本命名法了。

        3. 开启ViewBinding功能

        在 module级别的 build.gradle 文件中,添加如下代码:

        android {    ...    buildFeatures {        viewBinding true    }}

        如果你的 build.gradle 是 build.gradle.kts 这种文件,则这样添加代码:

        android {    ...    buildFeatures {        viewBinding = true    }}

        4. 生成绑定类

        添加配置代码之后,会提示你点击 sync 同步代码,然后 build 一下工程 AS 会自动为你的工程生成绑定类代码,目录在app/build/generated/data_binding_xxx下。

        生成的绑定类命名规则是,将 XML 文件的名称转换为“驼峰命名法”的形式,并在末尾添加“Binding”一词。比如,你的布局文件名是:activity_main.xml,那么生成的绑定类名是: ActivityMainBinding

        默认情况下,AS会对工程中的所有xml文件生成绑定类。如果不想为某个布局文件生成,则可以将 tools:viewBindingIgnore=“true” 属性添加到该布局文件的根视图中,例如:

            ...

        5. 使用ViewBinding

        ViewBinding可以用在各种需要布局与代码交互的地方,如Activity、Fragment、ViewHolder等

        5.1Activity 中使用

        首先是布局,不需要做任何修改,比如布局:activity_main.xml:

                    
        • 使用 ViewBinding 前

          MainActivity.kt :

          import androidx.appcompat.app.AppCompatActivityimport android.os.Bundleimport android.widget.Buttonimport android.widget.ImageViewimport android.widget.TextViewclass MainActivity : AppCompatActivity() {    private var tvTitle: TextView? = null    private var ivIcon: ImageView? = null    private var btnOk: Button? = null    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_main)        tvTitle = findViewById(R.id.tv_title)        ivIcon = findViewById(R.id.iv_icon)        btnOk = findViewById(R.id.btn_ok)        tvTitle?.text = "你好"        ivIcon?.setBackgroundColor(Color.RED)        btnOk?.text = "确认"        btnOk?.setOnClickListener {             Toast.makeText(this@MainActivity, "点击了", Toast.LENGTH_SHORT).show()        }    }}
        • 使用 ViewBinding 后

          MainActivity.kt :

          import android.graphics.Colorimport androidx.appcompat.app.AppCompatActivityimport android.os.Bundleimport android.widget.Toastimport com.example.mtes.databinding.ActivityMainBindingclass MainActivity : AppCompatActivity() {    private var activityMainBinding: ActivityMainBinding? = null    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        activityMainBinding = ActivityMainBinding.inflate(layoutInflater)        setContentView(activityMainBinding?.root)        activityMainBinding?.tvTitle?.text = "你好"        activityMainBinding?.ivIcon?.setBackgroundColor(Color.RED)        activityMainBinding?.btnOk?.text = "确认"        activityMainBinding?.btnOk?.setOnClickListener {            Toast.makeText(this@MainActivity, "点击了", Toast.LENGTH_SHORT).show()        }    }}

          到这里,相信你已经学会了 ViewBinding 的基本用法,体会到它的便捷了吧,再见了 findViewById 。

          5.2 Fragment 中使用

          这里就省略布局的举例了,跟Activity一样,拿到binding后,直接点出来你想访问的view即可。相信聪明的你一定能理解

          • 使用 ViewBinding 前,MyFragment.kt :
            import android.os.Bundleimport androidx.fragment.app.Fragmentimport android.view.LayoutInflaterimport android.view.Viewimport android.view.ViewGroupclass MyFragment : Fragment() {       override fun onCreateView(        inflater: LayoutInflater, container: ViewGroup?,        savedInstanceState: Bundle?    ): View? {        return inflater.inflate(R.layout.fragment_my, container, false)    }}
            • 使用 ViewBinding 后,MyFragment.kt :

              import android.os.Bundleimport androidx.fragment.app.Fragmentimport android.view.LayoutInflaterimport android.view.Viewimport android.view.ViewGroupimport com.example.mtes.databinding.FragmentMyBindingclass MyFragment : Fragment() {    private var binding: FragmentMyBinding? = null    override fun onCreateView(        inflater: LayoutInflater, container: ViewGroup?,        savedInstanceState: Bundle?    ): View? {        binding = FragmentMyBinding.inflate(layoutInflater, container, false)        val view = binding?.root        return view    }}

              5.3 ViewHolder 中使用

              列表也是我们常见的场景,使用 RecyclerView + Adapter + ViewHolder 实现列表,里面少不了对ViewHolder中的View的 findViewById。

              比如列表item布局: layout_holder.xml

                  
              • 使用ViewHolder前,MyAdapter.kt:

                import android.view.LayoutInflaterimport android.view.Viewimport android.view.ViewGroupimport android.widget.TextViewimport androidx.recyclerview.widget.RecyclerViewclass MyAdapter: RecyclerView.Adapter() {    private val dataList: List? = null    class MyViewHolder(val itemView: View) : RecyclerView.ViewHolder(itemView) {    }    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {        val view = LayoutInflater.from(parent.context).inflate(R.layout.layout_holder, parent, false)        return MyViewHolder(view)    }    override fun getItemCount(): Int {        return dataList?.size ?: 0    }    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {        val tvText: TextView = holder.itemView.findViewById(R.id.tv_item)        tvText.text = "你好"    }}
              • 使用ViewHolder后,MyAdapter.kt:

                import android.view.LayoutInflaterimport android.view.ViewGroupimport androidx.recyclerview.widget.RecyclerViewimport com.example.mtes.databinding.LayoutHolderBindingclass MyAdapter: RecyclerView.Adapter() {    private val dataList: List? = null    class MyViewHolder(val binding: LayoutHolderBinding) : RecyclerView.ViewHolder(binding.root) {    }    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {        val binding = LayoutHolderBinding.inflate(LayoutInflater.from(parent.context), parent, false)        return MyViewHolder(binding)    }    override fun getItemCount(): Int {        return dataList?.size ?: 0    }    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {        holder.binding.tvItem.text = "标题"    }}

                6. ViewBinding的优点

                与使用 findViewById 相比,视图绑定具有一些很显著的优点:

                • Null 安全

                  由于 ViewBinding 会创建对布局中的 view 的直接引用,因此不存在因 view ID 找不到而引发 null 指针异常的风险.

                • 类型安全

                  viewbinding 生成的属性类型和布局中的View类型是一致的,不存在之前findViewById后,类型转换的风险。

                  7. 与 dataBinding 对比

                  dataBinding 与 viewBinding 类似,也是可以生成绑定代码,但侧重点在于对于数据的赋值,相比 viewBinding 更复杂一些。因此如果只是想省略 findViewById ,那么推荐用 viewBinding 就好了,因为它有以下优势:

                  • 加快编译速度:视图绑定不需要处理注解,因此编译时间更短。
                  • 易于使用:视图绑定不需要特别标记的 XML 布局文件,因此在您的应用中采用的速度更快。在模块中启用视图绑定后,它会自动应用于该模块的所有布局。

                    另一方面,与 dataBinding 相比,viewBinding也有一些劣势:

                    • viewBinding 不支持布局变量或布局表达式,因此它不能用于直接从 XML 布局文件声明动态界面内容。
                    • viewBinding 不支持双向数据绑定。

                      最后,dataBinding 与 viewBinding 是可以同时使用的,在哪个页面用哪个,取决于你喽。

                      怎么样,有了 ViewBinding,妈妈再也不用担心你的手指了,快去试试吧~

                      如果这篇文章对你有用,欢迎支持

                      官网文档:https://developer.android.google.cn/topic/libraries/view-binding#groovy

上一篇:Java播放器源码深度解析与探究

下一篇:幻灯片大屏切换方法与技巧,轻松实现震撼展示!