本文首发于微信公众号「Android开发之旅」,欢迎关注 ,获取更多技术干货
咱们在Android开发的过程当中老是须要获取XML布局中的ViewId,以便给其赋值进行显示,早期咱们只能使用 findViewById 这个API,会致使不少的模版代码出现。2013年左右Android界大神 Jake Wharton开源了Butter Knife框架,经过Bind("viewid")方式方便开发者获取ViewId。近两年因为谷歌对Kotlin的支持,咱们开始使用 Android Kotlin extensions。 在文件中导入布局文件直接引用viewId。无需作其余额外操做,最为方便。android
目前,谷歌在 Android Studio 3.6 Canary 11 及更高版本中加入了新的视图绑定工具 ViewBinding。微信
下面咱们一块儿看下具体使用。框架
咱们如今开发不少项目都是使用模块化来进行开发的。ViewBinding也是很机智的能够按照模块来启用。若是要在某个模块中启用ViewBinding,则须要在模块的build.gradle中添加以下配置便可:ide
android { ... viewBinding { enabled = true } }
若是在使用的过程当中开发者不想为某个布局文件生成binding类,则可使用以下属性添加到布局的根视图中便可:模块化
<LinearLayout ... tools:viewBindingIgnore="true" > ... </LinearLayout>
当模块开启视图绑定功能后,系统会为该模块中的每个XML文件生成对应的绑定类。每个绑定类均包含对跟视图以及定义了ID的全部视图的引用。工具
绑定类的名称生成规则是将XML文件的名称按照驼峰命名规则加上Binding进行结尾。布局
好比咱们的 activity_main.xml文件。gradle
<LinearLayout ... > <TextView android:id="@+id/name" /> <ImageView android:cropToPadding="true" /> <Button android:id="@+id/button" android:background="@drawable/rounded_button" /> </LinearLayout>
那么生产的绑定类名称为 ActivityMainBinding。此类具备两个字段:一个是名为 name 的 TextView,另外一个是名为 button 的 Button。该布局中的 ImageView 没有 ID,所以绑定类中不存在对它的引用。ui
每一个绑定类还包含一个 getRoot() 方法,提供为布局文件的根视图的直接引用。在此示例中,ActivityMainBinding 类中的 getRoot() 方法会返回 LinearLayout 根视图。this
自动生成的绑定类也并不复杂,主要就是两个inflate重载方法以及一个bind方法。咱们获取的对viewId引用就是在bind方法中进行的,内部其实也是经过findViewById来获取相关view的。
咱们一般设置布局文件是经过setContentView("layoutId"),可是使用了ViewBinding后咱们须要按照以下方式进行设置layout:
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) //获取name进行赋值 binding.name.text = "viewBinding" } }
这样就能够直接使用了。是否是很简单呢。
可是须要注意的是,若是咱们的布局文件分为 layout和layout-land,咱们咱们在定义布局的时候可能会存在不一样的viewId,若是是使用findViewById 或者 Butter Knife 那么确定就异常了。
咱们在使用ViewBinding的时候,绑定类贴心的为咱们作了相关的判断。经过 @Nullable 和 @NonNull 两个注解来告诉开发者,哪些view可能为空。并在可能为空的view上添加了相关的注视说明。
/** * This binding is not available in all configurations. * <p> * Present: * <ul> * <li>layout/</li> * </ul> * * Absent: * <ul> * <li>layout-land/</li> * </ul> */ @Nullable public final TextView mAppTv;
提醒开发者在使用的时候注意异常的处理。
目前ViewBinding的功能还不够完善,好比XML中使用了 inClude 标签时没法对view进行引用。但整体来讲已经很不错了。相比较于 findViewById 和 Butter Knife两种方式仍是方便不少的。并且 ViewBinding 在使用的过程当中不存在类型转换以及空指针异常的问题。由于在绑定类中已经所有定义好了。开发者直接使用就能够。和 Android Kotlin extensions 相比较我以为都两者差很少。说不上谁更好。和databinding相比较就是数据绑定库仅处理使用 <layout> 代码建立的数据绑定布局。它具备局限性。
目前 Jake Wharton 也在 Butter Knife开源库中添加了以下一句话:
Attention: Development on this tool is winding down. Please consider switching to view binding in the coming months.
想必 ViewBinding 在将来的地位和做用将不言而喻了吧。