通过视图绑定功能,您可以更轻松地编写可与视图交互的代码。在模块中启用视图绑定之后,系统会为该模块中的每个 XML 布局文件生成一个绑定类。绑定类的实例包含对在相应布局中具有 ID 的所有视图的直接引用。
在大多数情况下,视图绑定会替代 findViewById。
启用
只能在 Android Studio 3.6 Canary 11 及更高版本中使用。
1 | android { |
启用后,会根据 xml 名称生成一个驼峰命名,结尾带上 Binding 的绑定类。例如:result_profile.xml,会生成 ResultProfileBinding 的绑定类,这个绑定类 getRoot 方法返回根布局,xml 中所有有 id 的 View 也能通过此类直接获取。相比于 kotlin-android-extensions,它不会空指针,并且 id 唯一。kotlin-android-extensions 直接获取对应 id 的 view 有可能导致空指针。另一点,如果我们很多 xml 里的 id 有一样的命名,会很难区分。且如果一个页面引用了 2 个 xml,这 2 个 xml 里是不能使用同样的 id 的,编译器会不知道要去找哪个 id 从而报错,而使用 viewBinding 这些便都解决了。
当然,或许某些时候,我们不需要生成绑定类,那么可以在布局根节点,添加tools:viewBindingIgnore="true"
即可:
1 | <LinearLayout |
在 Activity 中可以这样使用 viewBinding:
1 | private lateinit var binding: ResultProfileBinding |
封装 Base
那么基于 viewBinding 如何封装 Base 呢?写一下封装高德地图 RouteBaseMapFragment:
1 | abstract class RouteBaseMapFragment<VB : ViewBinding> : BaseFragment(), DefaultLocationListener { |
viewBinding 生成绑定类对应的基类是 ViewBinding,所以以此写相应的泛型即可。
封装 Multi-Type ItemBinder
项目中使用了 Multi-Type,每实现一个 ItemBinder,都需要实现 2 个方法:onCreateViewHolder、onBindViewHolder。那么结合 ViewBinding 就可以考虑将 onCreateViewHolder 给抽掉:
1 |
|
看一下 2 个 Base 封装,都是用 VB : ViewBinding 通过反射来找到相应的类,手动调用 inflate 方法即可。