Data Binding(四):事件监听
在之前的文章里,我写了如何在Android App中如何消除FindViewById(),同时解决View IDs的问题。有一件事情是我没有在之前文章中显示出来,即如何处理事件监听,例如View’s OnClickListener和TextView’s TextWatcher。
Android Data Binding 提供了三种在布局文件中设置事件监听的机制,你可以选择最适合你的方法。不同于基础的Android OnClick属性,在data binding的实践机制中没有使用反射,所以不论你选择哪一种方法都不会去影响性能。
Listener Objects
在任何一个可以使用set* 调用的listener(并不是add *调用的)的view中,你都可以绑定一个listener到它的属性上。如下:
<View android:onClickListener="@{callbacks.clickListener}" .../>
这个listener可以通过getter定义,或者通过一个public 字段定义:
public class Callbacks {
public View.OnClickListener clickListener;
}
还有一种简便的方法,即将Listener脱离开:
<View android:onClick="@{listeners.clickListener}" .../>
当应用程序已经使用侦听器对象时,将使用绑定与侦听器对象,但在大多数情况下,你将使用其他两种方法之一。
Method References
通过方法引用,你可以单独的连接方法到任何的事件监听器上。任何静态或者实例的方法都可以使用,只要它们在监听器中有相同的参数以及返回值。例如:
<EditText
android:afterTextChanged="@{callbacks::nameChanged}" .../>
这个叫nameChanged的回调方法代码如下:
public class Callbacks {
public void nameChanged(Editable editable) {
//...
}
}
这个属性总用在「Android」的明明空间中,并且在监听器中匹配相应名字的方法。
即使它不被建议,你可以在绑定的时候做一些逻辑处理:
<EditText android:afterTextChanged=
"@{user.hasName?callbacks::nameChanged:callbacks::idChanged}"
.../>
在大多数情况下把逻辑放在调用的方法里面是好的选择。当你将其他的信息传递给方法(如上面的user),这会变得更加的容易。你也可以通过lambda表达式做上面的事情。
Lambda Expressions
你可以提供一个lambda表达式,给你的方法里面传递任何参数。例如:
<EditText
android:afterTextChanged="@{(e)->callbacks.textChanged(user, e)}"
... />
textChanged方法接收传过来的参数:
public class Callbacks {
public void textChanged(User user, Editable editable) {
if (user.hasName()) {
//...
} else {
//...
}
}
}
要是你的监听器中没有参数,你可以移除它们:
<EditText
android:afterTextChanged="@{()->callbacks.textChanged(user)}"
... />
但是你无法只使用其中的几个—它们要不全在要不都不在。
表达式求值的时间在方法引用和lambda表达式之间也不同。通过方法引用,在绑定的时候验证表达式。使用lambda表达式,会在时间发生时候验证。
假设,回调的变量没有被设置。通过方法引用,表达式验证为空,不会有监听器被设置。通过Lambda表达式,监听器一直被设置,当事件发生时候验证表达式。通常这并不重要,但是当有一个返回值时,将返回默认的Java值,而不是没有调用。 例如:
<View android:onLongClick=”@{()->callbacks.longClick()}” …/>
当回调是空的时候,将会返回false。你可以使用一个长的表达式来将返回值设定成你所希望的:
<View android:onLongClick=”@{()->callbacks == null ? true : callbacks.longClick()}” …/>
你通常只是通过确保你没有null表达式求值来完全避免这种情况。
Lambda表达式和方法引用可以作用在相同的属性上,所以你可以方便的切换它俩。
挑选哪一个?
最灵活的方式当然是lambda表达式,它允许您为事件监听器提供的回调提供不同的参数。
在许多情况下,你的回调将采用与侦听器方法中给定的完全相同的参数。 在这种情况下,方法引用提供较短的语法,并且稍微更容易阅读。
在要转换为使用Android Data Binding的应用程序中,你可能已经在视图上设置了监听器对象。 您可以将侦听器作为变量传递到布局,并将其分配给视图。
原始文章地址(https://medium.com/google-developers/android-data-binding-adding-some-variability-1fe001b3abcc#.9zu7zob81)
历史文章记录: