DataBinding全解析2-事件处理

508 阅读3分钟

前言

事件处理是Android中最常见的功能,比如按钮的点击事件等,如果不使用数据绑定,就需要拿到这个按钮,给它设置对应的事件处理方法,但是通过数据绑定,就可以编写从视图分派的表达式处理事件。

这里主要分为2种,一种是方法引用,一种是监听器绑定。

正文

方法引用

方法引用这里要明白一件事,那就是方法签名,这个不论是C/C++函数指针还是kotlin的高阶函数我们都比较熟悉,也就是参数和返回值构成一个方法的签名。

所以在表达式中,想通过方法引用来处理事件则方法签名必须一样,否则会出错。

比如看个例子,给View设置方法引用,先看一下方法签名:

imgAppIcon.setOnClickListener(object : View.OnClickListener{
  override fun onClick(v: View?) {
      
  }
})

这个方法签名就是(View) -> null,那么就可以使用一个这个签名的方法来做引用:

fun imageClick(view: View){
    Log.i(TAG, "imageClick: 图片被点击")
}

然后就可以在xml中使用了,使用方法是使用 :: 来使用方法引用:

<ImageView
    android:id="@+id/imgAppIcon"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:scaleType="fitCenter"
    android:layout_marginTop="30dp"
    android:src="@mipmap/common_login_logo"
    android:onClick="@{viewModel::imageClick}"
    />

然而这里能成功有个很重要的前提就是onClick这个叫做事件特性名是和监听器方法的名称来确定,也就是它有个监听器的名字叫做setOnClickListener,再比如可以设置onTouch,它也有一个监听器叫做setOnToucherListener,所以也可以设置成功,从这里来看,这里还是有很大的局限性。

还有一个和下面方法的区别就是,方法引用是在数据绑定创建时就会去求值然后设置上,所以会出现编译错误,下面的监听器绑定是在事件触发时才去求值。

监听器绑定

监听器绑定是事件发生时运行的绑定表达式,这个啥意思呢?

和方法引用不同,比如点击事件onClick,当视图发生点击事件时才去求值表达式,然后进行处理。

还有一个和方法引用最大的区别就是方法应用中,必须签名完全一致也就是参数和返回值必须一样,但是在监听器绑定中没有这个要求,只需要返回值匹配即可。

直接看个例子:

<Button
    android:id="@+id/btnLogin"
    android:layout_width="match_parent"
    android:layout_height="42dp"
    android:layout_marginTop="24dp"
    android:textSize="17sp"
    android:background="@drawable/selector_login_btn"
    android:text="@string/login"
    android:textColor="@color/white"
    android:onClick="@{() -> viewModel.login()}"
    android:enabled="@{viewModel.enableButton}"
    />

在这个onClick中,就不是一个方法引用,因为它的签名完全不匹配,这里的意思就是当点击事件发生时,传递一个空参数给login()函数,login函数返回Unit即可,只要返回值一样即可:

fun login(){
    
}

当然这里也可以传递参数,也就是view。

总结

事件处理的原理非常简单,首先必须这些事件特征值要有对应的set监听器的方法,然后有2种方法来对事件进行处理,第一个就是要求签名一样的方法引用,还有就是只要求返回值一样的监听器绑定。