Google 在 Android Studio 3.6 Canary 11 及更高版本中提供了一个 viewBinding 的开关,可以开启视图绑定功能,以此来替代 findViewById

viewBinding功能可按模块启用。要在某个模块中启用viewBinding,请将 viewBinding 元素添加到其 build.gradle 文件中,如下例所示:

android {...viewBinding {enabled = true}
}

如果您希望在生成绑定类时忽略某个布局文件,请将 tools:viewBindingIgnore="true" 属性添加到相应布局文件的根视图中:

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

为某个模块启用视图绑定功能后,系统会为该模块中包含的每个 XML 布局文件生成一个绑定类。每个绑定类均包含对根View以及具有 ID 的所有View的引用。系统会通过以下方式生成绑定类的名称:将 XML 文件的名称转换为驼峰式大小写,并在末尾添加“Binding”。

例如,假设某个布局文件的名称为 result_profile.xml

<LinearLayout ... ><TextView android:id="@+id/name" /><ImageView android:cropToPadding="true" /><Button android:id="@+id/button"android:background="@drawable/rounded_button" />
</LinearLayout>

所生成的绑定类的名称就为 ResultProfileBinding。此类具有两个字段:一个是名为 nameTextView,另一个是名为 buttonButton。该布局中的 ImageView 没有 ID,因此绑定类中不存在对它的引用。

每个绑定类还包含一个 getRoot() 方法,用于为相应布局文件的根View提供直接引用。在此示例中,ResultProfileBinding 类中的 getRoot() 方法会返回 LinearLayout 根视图。

在 Activity 中使用 viewBinding

如需设置绑定类的实例以供 Activity 使用,请在 Activity 的 onCreate() 方法中执行以下步骤:

  1. 调用生成的绑定类中包含的静态 inflate() 方法。此操作会创建该绑定类的实例以供 Activity 使用。
  2. 通过调用 getRoot() 方法或使用 Kotlin 属性语法获取对根View的引用。
  3. 将根视图传递到 setContentView(),使其成为屏幕上的活动View。
    private lateinit var binding: ResultProfileBindingoverride fun onCreate(savedInstanceState: Bundle) {super.onCreate(savedInstanceState)binding = ResultProfileBinding.inflate(layoutInflater)val view = binding.rootsetContentView(view)}

然后即可使用该绑定类的实例来引用任何View控件:

binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }

在 Fragment 中使用 viewBinding

如需设置绑定类的实例以供 Fragment 使用,请在 Fragment 的 onCreateView() 方法中执行以下步骤:

  1. 调用生成的绑定类中包含的静态 inflate() 方法。此操作会创建该绑定类的实例以供 Fragment 使用。
  2. 通过调用 getRoot() 方法或使用 Kotlin 属性语法获取对根View的引用。
  3. onCreateView() 方法返回根View,使其成为屏幕上的活动View。
    private var _binding: ResultProfileBinding? = null// This property is only valid between onCreateView and onDestroyView.private val binding get() = _binding!!override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?): View? {_binding = ResultProfileBinding.inflate(inflater, container, false)val view = binding.rootreturn view}override fun onDestroyView() {super.onDestroyView()_binding = null}

然后即可使用该绑定类的实例来引用任何View控件:

binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }

注意:inflate() 方法会要求传入LayoutInflater对象。如果布局已经inflated,则可以调用绑定类的静态 bind() 方法。 例如:

/*** View Binding example with a fragment that uses the alternate constructor for inflation and* [onViewCreated] for binding.*/
class BindFragment : Fragment(R.layout.fragment_blank) {// Scoped to the lifecycle of the fragment's view (between onCreateView and onDestroyView)private var fragmentBlankBinding: FragmentBlankBinding? = nulloverride fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)val binding = FragmentBlankBinding.bind(view)fragmentBlankBinding = bindingbinding.textViewFragment.text = getString(string.hello_from_vb_bindfragment)}override fun onDestroyView() {// Consider not storing the binding instance in a field, if not needed.fragmentBlankBinding = nullsuper.onDestroyView()}
}

注意:Fragment 的存在时间比其视图长。请务必在 Fragment 的 onDestroyView() 方法中清除对绑定类实例的所有引用。

与 findViewById 的区别

与使用 findViewById 相比,viewBinding具有一些很显著的优点:

  • Null 安全:由于viewBinding会创建对View的直接引用,因此不存在因View ID 无效而引发空指针异常的风险。此外,如果View仅出现在布局的某些配置中,则绑定类中包含其引用的字段会使用 @Nullable 标记。
  • 类型安全:每个绑定类中的字段均具有与它们在 XML 文件中引用的View相匹配的类型。这意味着不存在发生类转换异常的风险。

这些差异意味着布局和代码之间的不兼容将会导致构建在编译时(而非运行时)失败。

与 dataBinding 的对比

viewBinding和dataBinding 均会生成可用于直接引用视图的绑定类。但是,viewBinding旨在处理更简单的用例,与dataBinding 相比,具有以下优势:

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

反过来,与 dataBinding 相比,viewBinding 也具有以下限制:

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

替代 KAE

viewBinding 还有一个重要作用是替代以前的 Kotlin Android Extensions,在之前的kotlin版本中提供了一个针对android的扩展插件,它可以允许我们直接用布局文件中的 view id 来访问 view,也无需写 findViewById。

但是由于 KAE 存在一些潜在的 bug (例如可以访问到不属于当前Activity布局的view id造成空指针异常等), 从 Kotlin 1.7 开始,KAE被正式移除了。

那么 viewBinding 的出现也是为了弥补之前 KAE 的功能和缺陷。


最后,viewBinding 只是针对传统 View 体系的开发,在进入 Jetpack Compose 的世界以后,这项功能就基本无用武之地了。

Android Studio 开启视图绑定 viewBinding相关推荐

  1. 【JetPack】为现有 Android 项目配置视图绑定 ( ViewBinding ) 模块 ( 视图绑定不影响传统布局操作 | 视图绑定类关联 Activity | 视图绑定类本质 )

    文章目录 I . 为现有项目配置 视图绑定 ( ViewBinding ) 应用 II . 视图绑定 ( ViewBinding ) 定制 III . 视图绑定 ( ViewBinding ) 对于正 ...

  2. Android视图绑定ViewBinding的使用

    前言 后台读者留言:能否写一篇视图绑定ViewBinding相关的内容? 首先感谢这位读者的提议,让我抽出时间细看视图绑定的内容,也打算在项目中使用该功能.当然,还有其他读者提议的内容我已记录,后期有 ...

  3. 【JetPack】视图绑定 ( ViewBinding ) 各种应用 ( 视图绑定两种方式 | Activity 布局 | 对话框布局 | 自定义组件布局 | RecyclerView 列表布局 )

    文章目录 I . 视图绑定 ( ViewBinding ) 界面的两种方式 II . Activity 界面中 应用 视图绑定 ( ViewBinding ) III . Dialog 对话框界面中 ...

  4. Android Studio自定义视图无法预览

    Android Studio自定义视图没有办法预览 我想大家应该都和我一样,如果看到布局的编码的时候如果右边能够非常直观地显示出对应的视图,心里会非常舒心,像官方提供的tools命名空间就是为了这个目 ...

  5. Android Studio开启虚拟机报错!emulator: ERROR: x86 emulation currently requires hardware acceleration!解决办法梳理

    1.如果确认电脑没有开启Intel Virtualization Technology,那么先进BIOS里开启,然后再进行如下步骤,如果不确认,进入第二步. 2.到Android SDK的安装路径下, ...

  6. Android Studio中视图的inputType属性3-1

    inputType属性一般用于TextView或者EditText视图,表示输入内容的类型.inputType的取值有很多,主要分为英文文本输入.数字输入.密码输入等几大类. 1 英文文本输入 当输入 ...

  7. Android Studio开启DDMS查看手机文件

    不想打字,看图 还是打点字吧,上面不能直接查看文件,要看的话,点击导出然后方可查看

  8. 【JetPack】ViewBinding 视图绑定组件 ( 启用模块 | 视图绑定定制 | 绑定类名称生成规则 | 绑定类字段生成规则 | 绑定类获取根视图 | 绑定类获取布局组件 )

    文章目录 I . 视图绑定组件简介 II . 视图绑定 ViewBinding 使用前提 ( Android Studio 3.6 ) III . 视图绑定组件启用 IV . 定制视图绑定 ( 启用视 ...

  9. 将视图转为image_使用视图绑定替代 findViewById

    从 Android Studio 3.6 开始,视图绑定能够通过生成绑定对象来替代 findViewById,从而可以帮您简化代码.移除 bug,并且从 findViewById 的模版代码中解脱出来 ...

最新文章

  1. 删除Windows 系统快捷方式箭头 Delete Windows Shortcuct Arrows
  2. javascript一个重要知识点:事件。
  3. 算法设计与分析(第三周)递归/迭代求Fibonacci前n项 【以及递归算法速度慢的原因】
  4. 通用Excel文件导出工具类
  5. 1补码 2补码_8085微处理器中8位数字的1和2的补码
  6. 知乎:fastjson这么快,为啥老外还是热衷 jackson?
  7. POM思想__多个页面时进行的处理
  8. idea Spring-boot 项目debug启动过慢 spring debug启动过慢解决办法:已解决
  9. One-hot 编码/TF-IDF 值来提取特征,LAD/梯度下降法(Gradient Descent),Sigmoid
  10. 读书笔记:windows程序设计
  11. 蓝牙技术谈之调频技术(一)
  12. 平面变压器的设计(翻译)(1)
  13. vue实现文件下载功能
  14. [填坑] 解决 Ubuntu ssh 登录自动休眠问题
  15. SyntaxError: Non-UTF-8 code starting with ‘\xb5‘ in file问题如何解决???求助求助!!!
  16. 跟着钱钟书和杨绛去春游
  17. 论文阅读笔记(7-1)---Supervised Contrastive Learning
  18. Python爬取网上车市[http://www.cheshi.com/]的数据
  19. ES6——ES6内置对象
  20. 怎么把桌面计算机放到快速启动栏,如何设置电脑快速启动?

热门文章

  1. hashing (哈希)
  2. hash和history的原理和区别
  3. 90后女孩经营茶叶生意,已累计有近400个固定用户
  4. 展望2016:光伏消纳矛盾应如何破解?
  5. 2019年12月Eclipse下载与安装
  6. U3D:添加、删除Component
  7. 走了索引为啥还像蜗牛一样?
  8. 基于OpenGL的计算机图形机械零件车工建模模拟
  9. HDI PCB 板 0.1mm 以下的孔不好造?它不服
  10. 百无聊赖之JavaEE从入门到放弃(九)封装详解 多态详解