Kotlin 中的 DataBinding

Kotlin 中的 DataBinding_第1张图片
image.png

前言


  • 前面一章和大家简单的讲解了 Kotlin 中的变量、方法以及对象声明的定义,今天呢,就和大家讲讲 Kotlin 中的 DataBinding 的使用。
  • KotlinTest Github:

添加 DataBinding 依赖


  • 在我之前的文章里就有说过如何在项目中使用 DataBinding,当然了,那是在 Java 语言开发中,要是使用 Kotlin 开发的话,还是有所区别的。不了解的可以看看我之前的 Android项目基本架构(四) DataBinding

  • 如果使用 Java 开发,那么很简单,只需要在 Module 的 gradle 文件中 android 节点下加入相应设置就可以了:

      android {
          ...
          dataBinding {
              enabled true
          }
          ...
      }
    
  • 但是使用 Kotlin 开发这样是远远不够的,除此之外,你还需要手动添加上注解处理依赖,而使用注解处理,你又要添加 kapt 插件支持:

      apply plugin: 'com.android.application'
      apply plugin: 'kotlin-android'
      apply plugin: 'kotlin-android-extensions'
      apply plugin: 'kotlin-kapt'      // 添加 kapt 插件支持
    
      android {
          ...
          dataBinding { // 开启 DataBinding
              enabled true
          }
          ...
      }
    
      kapt {  // kapt 配置
          generateStubs = true
      }
    
      dependencies{
          ...
          kapt 'com.android.databinding:compiler:2.3.3  // DataBinding 注解处理依赖
          ...
      }
    
  • Kotlin 中 DataBinding 配置就完成了。

Observable


  • 你以为配置好依赖就可正常使用了吗?那你就太天真了,Kotlin 和 Java 还是有很大不同的。

  • 还记得 Java 中的用法吗?

      public class Entity extends BaseObservable {
          private boolean show;
    
          @Bindable
          public boolean isShow() {
              return show;
          }
    
          public void setShow(boolean show){
              this.show = show;
              notifyPropertyChanged(BR.show);
          }
      }
    
  • 没错就是这样,@Bindable 注解将变量 show 和 xml 中的布局绑定起来,通过 setShow() 方法变化 show 的值时,xml 中与之对应的布局也会随之变化。

  • 但是在 Kotlin 中你是不用像 Java 中一样手动去生成 getter 和 setter 的, Kotlin 中你只需要声明一个属性,那么就会自动生成默认的 getter 、setter。

      class Entity : BaseObservable() {
          var show: Boolean = false
      }
    
  • 在使用 Kotlin 的时候你会发现很多代码像这样:list.adapter = ListAdapter(),这其实是调用了默认的 setter。

  • 这个时候,该怎么使用 Observable 呢?之前查找资料的时候看到很多文章多说没有办法像 Java 中一样使用,需要使用 ObservablerBoolean、ObservableString 等封装类,但是实际上是不用这样的,因为虽然 Kotlin 有默认的 getter、setter,但是同样你也可以自己进行定义。

  • 如果你不知道如何定义,可以使用 Kotlin 提供的工具 Convert Java File to Kotlin File 将 Java 代码转换为 Kotlin 代码,于是就成了这样:

      class Entity : BaseObservable {
          @set:Bindable
          var id: Int = 0
              set(id) {
                  field = id
                  notifyPropertyChanged(BR.id)
              }
      }
    
  • 所有的 Observable 都可以以这种形式定义。

Component


  • 但是,你要知道, Kotlin 提供的 Convert Java File to Kotlin File 工具并不是完美的,很多地方并不是直接这么转换就可以了。

  • 在 Java 中使用 DataBindingAdapter 是这样的

      public class DatBindingAdapter {
          @BindingAdapter("img_url")
          public static void imgUrl(ImageView iv, String imgUrl) {
              Glide.with(iv.getContext())
                  .load(imgUrl)
                  .into(iv);
          }
      }
    
  • 如果你在这里使用工具进行转换,你会发现他会转换成对象声明:

      object DataBindingAdapter {
          @BindingAdapter("img_url")
          fun imgUrl(iv: ImagerView, imgUrl: String) {
              Glide.with(iv.getContext())
                  .load(imgUrl)
                  .into(iv);
          }
      }
    
  • 这样的话在使用的时候就会报错,因为方法不是静态的,这个时候就有两种解决方式。

  • 如果你不想变动 DataBindingAdapter 的内容,那么你就要在使用 DataBinding 前对 Component 进行设置,比如在 Application 类中:

      class MyApplication : Application() {
          override fun onCreate() {
              super.onCreate() 
              DataBindingUtil.setDefaultComponent(object : DataBindingComponent { // 手动设置 Component
                  ovverride fun getDataBindingAdapter() : DataBindingAdapter {
                      return DataBindingAdapter
                  }
              })
          }
      }
    
  • 这样设置后就可以正常使用了,这里的 object : DataBindingComponent{} 可能有些难以理解,实际上就等同于 Java 中的匿名内部类:

      DataBindingUtil.setDefaultComponent(new DataBindingComponent{
          @Override
          public DataBindingAdapter getDataBindingAdapter() {
              return new DataBindingAdapter();
          }
      });
    
  • 如果你觉得这样设置麻烦,你也可以选择另一种做法:

      class DataBindingAdapter{
          companion object {
              @BindingAdapter("img_url")
              @JvmStatic
              fun imgUrl(iv: ImagerView, imgUrl: String) {
                Glide.with(iv.getContext())
                    .load(imgUrl)
                    .into(iv);
              }
          }
      }
    
  • 使用 BindingAdapter 要不就手动设置 Component,要不就将方法定义为静态的。

  • 但是,Java 的 static 关键字并不是 Kotlin 语言的一部分,作为替代,Kotlin 提供了包级别函数(我们之后在详细说明)和对象声明。

  • 在我的上一篇文章中说到了对象声明,使用关键字 object,一定义即存在。上面的代码中涉及到了 Kotlin 中的伴生对象,使用 companion 关键字修饰,伴生对象中的属性、方法可以直接通过类名.调用,即 DataBindingAdapter.imgUrl(iv, imgUrl) ,类似于 Java 中的静态常量、静态方法。但是,这样还是不够,因为这并不是静态方法,只是类似,这时就要使用注解 @JvmStatic 来标记这个方法就是静态方法。这样 DataBindingAdapter 就可以正常使用了。

最后


  • 关于 DataBinding 在 Kotlin 中的使用就是这样,如果使用中有什么问题可以在评论区提问。
  • 接下来还会继续加入 Dagger2 、基类封装等,欢迎关注~
  • 最后的最后,Android Studio 3.0 发布正式版啦~

你可能感兴趣的:(Kotlin 中的 DataBinding)