Kotlin 中的 DataBinding

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 发布正式版啦~
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,820评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,648评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,324评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,714评论 1 297
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,724评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,328评论 1 310
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,897评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,804评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,345评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,431评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,561评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,238评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,928评论 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,417评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,528评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,983评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,573评论 2 359

推荐阅读更多精彩内容