DataBinding系列二、绑定事件处理方法

绑定事件处理方法到view,当view的事件发生时,调用这些方法处理事件。
有两种绑定方法:Method References(方法引用)和Listener Bindings(监听绑定)。

Method References

这种方法类似于在布局文件中定义android:onClick属性,然后在activity中定义相关的方法,但是要强大得多,在编译的时候就绑定了,这样不用担心运行时报错了(activity那种是运行时报错,直接崩溃)。用一个例子来说明一下,我们的目标是点击一个TextView弹出“hello”信息,长按它弹出”hello world”信息。

1. 创建响应方法

方法的签名(signature)要和处理事件用的listener完全一样,比如对于view的onClick事件,它对应的listener的处理方法是:

    public interface OnClickListener {
        void onClick(View v);
    }

在而长按事件是

    public interface OnLongClickListener {
        boolean onLongClick(View v); //注意它的返回参数是boolean
    }

注意只要签名一致,所以我们创建如下响应方法:

public class MyHandler {
    public void myOnClick(View view){
        Toast.makeText(view.getContext(),"hello",Toast.LENGTH_SHORT).show();
    }
    public boolean myOnLongClick(View view){
        Toast.makeText(view.getContext(),"hello world",Toast.LENGTH_SHORT).show();
        return true;
    }
}

2.在布局文件中设置

<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="handlers" type="com.heyy.databingexample.MyHandler"/>
    data>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="测试事件绑定"
            android:onClick="@{handlers::myOnClick}"
            android:onLongClick="@{handlers::myOnLongClick}"/>
    LinearLayout>
layout>

3. 在代码中进行绑定

同样简单点在onCreate中绑定:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        activityMainBinding.setHandlers(new MyHandler());
    }

Listener Bindings

要求 android plugin 2.0+
比起Method References,这种方法多了一些特性,它是在事件发生以后才绑定的。
这种方法不再要求签名一致,而只是要求返回值一样,这样我们可以自己定制参数,用刚刚那个例子来重写一下。

1.创建响应方法

这次我们在里面加一个参数

public class MyHandler {
    public void myOnClick(View view, String name) {
        Toast.makeText(view.getContext(), "hello " + name, Toast.LENGTH_SHORT).show();
    }
}

2.在布局文件中设置

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable name="handlers" type="com.heyy.databingexample.MyHandler"/>
    data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="测试事件绑定"
            android:onClick="@{(view)->handlers.myOnClick(view,"CrazyMan")}"
            android:onLongClick="@{handlers::myOnLongClick}"/>
    LinearLayout>
layout>

注意,传递String参数时使用了"CrazyMan",引号等需要使用HTML字符实体。
整个响应表达式是一个lambda表达式,在编译的时候数据绑定会创建一个默认响应方法,当事件触发时,默认响应方法执行这个lambda表达式。lambda表达式可以根据->分成两部分:
->左边的部分是(view) ,这里是原来listener中void onClick(View v)中的参数,这个参数必须全部写或者全部不写。比如对于:

public static interface OnCheckedChangeListener {
        void onCheckedChanged(CompoundButton buttonView, boolean isChecked);
    }

那么lambda左边的部分可写成
(view,checked)-> 或 ()->
简单来说,要么全写要么全不写,be alive or be die no other choice.
lambda表达式,还可以这样:

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

简单来说,就是可以在xml执行代码,google推荐只写非常简单的逻辑(不包含任何业务逻辑),否则导致xml变复杂,会变得很难读很难管理。

3.在代码中绑定

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        activityMainBinding.setHandlers(new MyHandler());
    }

两种方法的比较

  1. Method References方法要求比较低(gradle plugin 1.5+),Listener Bindings要求高(gradle plugin 2.0+)。
  2. Method References要求响应方法的签名和事件listener中的签名完全一致,Listener Bindings只要求返回值一致。
  3. Method References在编译时绑定,Listener Bindings在运行时才会执行绑定lambda表达式。
  4. Method References不可以自定义参数,Listener Bindings可以自定义参数。
  5. Listener Bindings可以编写简单的代码逻辑。

onClick冲突

有些View中有特殊的onClick事件,在xml中使用其他属性名字来解决和真实onClick事件的冲突:
这里写图片描述

你可能感兴趣的:(Android)