美文网首页databinding
DataBinding(三)事件处理

DataBinding(三)事件处理

作者: timshinlee | 来源:发表于2018-03-21 16:56 被阅读0次

    DataBinding可以在XML中使用事件的回调方法名作为属性名(大部分情况下)来处理View分发的事件。比如说View.OnLongClickListener的回调方法是onLongClick,所以这个事件的属性名称就是android:onLongClick。

    事件的处理可以有两种方式:

    1. 方法引用:在事件属性的表达式中调用一个方法,这个方法的签名必须和事件回调方法签名一致。当事件回调发生时,就会去转而调用传入的这个方法。如果事件表达式为空,则只会给目标view的事件回调设置一个空的监听器。
    2. 监听器绑定:属性值表达式是一个lambda表达式,总会创建一个监听器来设置到目标view上,事件发生的时候才会执行这个表达式。

    这两种方式的主要区别是方法引用在绑定时就已经给view设置了相对应的监听了,而监听器绑定是方法触发时才会去执行表达式设置监听。

    1. 方法引用

    android:onClick可以直接引用一个Activity中声明的方法一样,事件也可以直接绑定到某个类的方法中,注意所绑定方法的参数必须与事件方法参数一致,同时返回值也必须一致。与View#onClick属性相比,这种方式的优点在于如果未设置相应回调方法,则编译期就会报错,不会等到运行时报错崩溃。使用示例:

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android">
       <data>
           <variable name="handlers" type="com.example.MainActivity"/>
           <variable name="user" type="com.example.User"/>
       </data>
       <LinearLayout
           android:orientation="vertical"
           android:layout_width="match_parent"
           android:layout_height="match_parent">
           <TextView 
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:text="@{user.firstName}"
               android:onClick="@{handlers::onClickFriend}"/>
       </LinearLayout>
    </layout>
    
    public class MainAcivity extends Activity {
        public void onClickFriend(View view) { ... }
    }
    

    调用语法可以是@{handlers::onClickFriend}或者@{handlers.onClickFriend}

    2. 监听器绑定

    事件发生时才会执行属性值里的表达式。跟方法引用不同的是,表达式内可以写任意的DataBinding表达式。而且监听器绑定可以定义不同的参数类型,只要表达式返回值与事件方法返回值一致就可以了,如果事件方法返回值是空,表达式可以不用返回。

    监听器绑定的格式如下:

    public class Presenter {
        public void onSaveClick(Task task){}
    }
    
    <!-- XML -->
     <?xml version="1.0" encoding="utf-8"?>
     <layout xmlns:android="http://schemas.android.com/apk/res/android">
         <data>
             <variable name="task" type="com.android.example.Task" />
             <variable name="presenter" type="com.android.example.Presenter" />
         </data>
         <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent">
             <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
             android:onClick="@{() -> presenter.onSaveClick(task)}" />
         </LinearLayout>
     </layout>
    

    使用的是lambda表达式,并且lambda表达式必须是表达式的最外层。

    上述格式中我们省略了onClick的参数View,监听器绑定中可以省略所有或者列出所有监听器的参数。列出所有参数的格式如下:

     android:onClick="@{(view) -> presenter.onSaveClick(task)}"
    

    声明了参数之后就可以在表达式中使用:

    public class Presenter {
        public void onSaveClick(View view, Task task){}
    }
    
    <!-- XML -->
      android:onClick="@{(theView) -> presenter.onSaveClick(theView, task)}"
    

    Lambda表达式多个参数的示例:

     <CheckBox 
            android:layout_width="wrap_content" android:layout_height="wrap_content"
            android:onCheckedChanged="@{(cb, isChecked) -> presenter.completeChanged(task, isChecked)}" />
    

    注意监听器绑定的返回值必须与回调方法返回值一致,例如:

    public class Presenter {
        public boolean onLongClick(View view, Task task){}
    }
    
    <!-- XML -->
     android:onLongClick="@{(theView) -> presenter.onLongClick(theView, task)}"
    

    假如监听器方法返回null,则会为回调方法返回其返回值的默认值。

    另外可以在lambda表达式中可以使用void:

     android:onClick="@{(v) -> v.isVisible() ? doSomething() : void}"
    

    相关文章

      网友评论

        本文标题:DataBinding(三)事件处理

        本文链接:https://www.haomeiwen.com/subject/qbngqftx.html