Data binding的使用(二)-----事件的绑定监听

官网地址:Google Android Data Binding Library

Demo地址:(https://github.com/zhangiqlin/DataBindingDemo)

上一篇文章Data binding的使用(一)讲了一些基础的关于如何开始使用Data Binding做了一些介绍,这篇文章继续讲解使用Data Binding的一些其他操作,比如点击事件,或者监听对象的值的变化,做出及时的修改。

补充前面

前面忘了说了,Data Binding中可传递任意类型的参数,比如int,String,数组或者Drawable对象,但是注意某些对象需要使用全称比如Drawable 引用的时候应该这样引用
"img"
            type="android.graphics.drawable.Drawable"/>

在type中应该使用全称

Data Binding 事件的处理

Event Handling
Data Binding allows you to write expressions handling events that are dispatched from the views (e.g. onClick). Event attribute names are governed by the name of the listener method with a few exceptions. For example, View.OnLongClickListener has a method onLongClick(), so the attribute for this event is android:onLongClick. There are two ways to handle an event.

Method References: In your expressions, you can reference methods that conform to the signature of the listener method. When an expression evaluates to a method reference, Data Binding wraps the method reference and owner object in a listener, and sets that listener on the target view. If the expression evaluates to null, Data Binding does not create a listener and sets a null listener instead.
Listener Bindings: These are lambda expressions that are evaluated when the event happens. Data Binding always creates a listener, which it sets on the view. When the event is dispatched, the listener evaluates the lambda expression.

这里讲了一种是方法的引用Method References 举个例子吧。

第一种 Method References(方法引用)

创建一个MainActivityPresenter类,

public class MainActivityPresenter {

    public void myTextOnClick(View view) {
        Toast.makeText(view.getContext(), "hello dataBind", Toast.LENGTH_SHORT).show();
    }
}

注意:该方法不能写成private的不然运行的时候会提示报错。且方法参数要有View作为参数名称

然后在布局文件中添加声明该类。


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

    <data>

        <variable
            name="user"
            type="simple.qilin.com.databindingdemo.bean.User">variable>

        <variable
            name="mainPrecenter"
            type="simple.qilin.com.databindingdemo.precenter.MainActivityPresenter">variable>
    data>

    <LinearLayout
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="simple.qilin.com.databindingdemo.MainActivity">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{user.name}"
            android:textSize="16sp"
            />

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="@color/colorAccent"
            >View>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="12dp"
            android:onClick="@{mainPrecenter.myTextOnClick}"
            android:text="点我啊"
            />
    LinearLayout>
layout>

可以看见 上面代码中声明了

<variable
            name="mainPrecenter"
            type="simple.qilin.com.databindingdemo.precenter.MainActivityPresenter">variable>

最后在使用的时候我们调用了MainActivityPresenter 类的myTextOnClick方法

 <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="12dp"
            android:onClick="@{mainPrecenter.myTextOnClick}"
            android:text="点我啊"
            />

最后在Activity类中设置xml中声明的引用对象

public class MainActivity extends AppCompatActivity {
    private final static String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ActivityMainBinding activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        User user = new User("My Name is X");
        activityMainBinding.setUser(user);
        activityMainBinding.setMainPrecenter(new MainActivityPresenter());
    }
}

最后看看效果吧。

这样就简单的实现了我们的方法绑定。

看见官网中在xml中使用的绑定方法是

<TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.firstName}"
           android:onClick="@{handlers::onClickFriend}"/>

这里使用了2个冒号:: 来调用方法,实践过程中,会提示报错,也是百思不得其解啊。这里我们直接通过对象.方法名称 来调用的。

第二种(Listener Bindings)监听绑定的方式

官网说明了不同点,

Listener Bindings are binding expressions that run when an event happens. They are similar to method references, but they let you run arbitrary data binding expressions. This feature is available with Android Gradle Plugin for Gradle version 2.0 and later.

In method references, the parameters of the method must match the parameters of the event listener. In Listener Bindings, only your return value must match the expected return value of the listener (unless it is expecting void)

google翻译了一下,

侦听器绑定是在事件发生时运行的绑定表达式。 它们与方法引用类似,但它们允许您运行任意数据绑定表达式。 此功能适用于Gradle版本2.0及更高版本的Android Gradle插件。

在方法引用中,方法的参数必须与事件侦听器的参数相匹配。 在侦听器绑定中,只有您的返回值必须与侦听器的预期返回值相匹配(除非它是期望的void)。 例如,您可以有一个演示者类具有以下方法:

这里我们做了一个演示

修改precenter代码如下


public class MainActivityPresenter {
    private Context mContext;

    public MainActivityPresenter(Context context) {
        mContext = context;
    }

    public void myTextOnClick(View view) {
        Toast.makeText(view.getContext(), "hello dataBind", Toast.LENGTH_SHORT).show();
    }

    public void testListenerBindingClick() {
        Toast.makeText(mContext, "打雷了 收衣服了。。。", Toast.LENGTH_SHORT).show();
    }

    public String getTextStr() {
        return "天气阴";
    }
}

修改xml代码如下


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

    <data>

        <variable
            name="user"
            type="simple.qilin.com.databindingdemo.bean.User">variable>

        <variable
            name="mainPrecenter"
            type="simple.qilin.com.databindingdemo.precenter.MainActivityPresenter">variable>
    data>

    

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{() -> mainPrecenter.testListenerBindingClick()}"
            android:padding="12dp"
            android:text="查询天气"
            />

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="@color/colorAccent"
            >View>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{() -> mainPrecenter.testListenerBindingClick()}"
            android:padding="12dp"
            android:text="@{mainPrecenter.getTextStr()}"
            />
    LinearLayout>
layout>

这里可以看到 我调用的时候是通过

@{() -> mainPrecenter.testListenerBindingClick()}

这样的方式去调用的,对应的方法为

public void testListenerBindingClick() {
        Toast.makeText(mContext, "打雷了 收衣服了。。。", Toast.LENGTH_SHORT).show();
    }

这里不需要传递参数,
其中一个TextView 的 android:text="@{mainPrecenter.getTextStr()}" 可以看到对应的方法为

public String getTextStr() {
        return "天气阴";
    }

这里是带有返回值的,看看最终的效果

可以看见最后获取了从precenter中返回的天气,我们添加的点击事件也能正常显示,

下面试试在xml给方法事件传递参数试试 新增xml代码如下

<TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:hint="看看我叫啥?"
            android:onClick="@{(theview) -> mainPrecenter.getMyName(theview,user)}"
            android:padding="12dp"
            />

这里引用的为@{(theview) -> mainPrecenter.getMyName(theview,user)} 其中theview这个代表当前这个View,名字可以随便起,但是必须和后面参数名中的名字一致,传递的user为之前传递进来的User对象。
percenter添加方法

   public String getMyName(View view, User user) {
        Toast.makeText(view.getContext(), user.name, Toast.LENGTH_SHORT).show();
        TextView textView = (TextView) view;
        textView.setText(user.name);
        return user.name;
    }

结果:

是不是很好玩啊。我们只需要在precenter中做操作,不需要再Activity做任何处理了,这样Activity就变得干净了。一些逻辑就可以直接在Precenter中处理了。

结尾

这里我们讲了事件绑定的方法,有2种方式提供,大家可根据自己的需要选择看哪种更适合自己。好了今天先就到这里,还是没能写到如何动态修改视图中的值 ,下次再讲吧。。。

你可能感兴趣的:(android)