学习自Google文档以及大帅的博客,文末地址链接。
1. DataBinding
自从Google加入了DataBing,还是很受开发者喜爱的,所以,咱也来学习下DataBinding是什么鬼东西。
在gradle文件的android节点下。添加如下配置,就开启了DataBinding。
dataBinding {
enabled = true
}
下面有几点说明:
- 下文所有代码均在Android Studio 2.2 上
- Jack编译链暂不支持DataBinding
- 编译器智能提示还是有点弱鸡
- 遇到报红,别慌
- 等等
2. DataBinding尝鲜
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
>
<data class="CustomLayout">
<variable
name="user"
type="beans.User"/>
<variable
name="handler"
type="events.SaveHandler"/>
</data>
<LinearLayout
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{user.username}"
android:onClick="@{()->handler.saveUser(user)}"
/>
</LinearLayout>
</layout>
- layout下包含两部分内容
- 对应数据部分
- 声明的变量
- 布局部分
- @{} 的形式去用声明的变量
在我们对应的Activity下,修改代码如下
CustomLayout layoutBinding = DataBindingUtil.setContentView(this,R.layout.custom_activity);
User user = new User("custom");
layoutBinding.setVariable(BR.user,user);
而其中对应的CustomLayout是什么呢?这是我在这里自定义的DataBingding的类名,是在xml中data部分通过class属性指定的。如果我们没有指定,就会按照布局文件名去生成,如activity_main.xml生成的就是ActivityMainBinding。关于自定义对应DataBinding类名
就这样,我们就完成了数据的绑定。不要停,我们继续来看事件的绑定
3.事件的绑定。
事件绑定分为两种
- 方法引用
- 监听事件
3.1 方法引用
先声明接口。
public interface ClickHandler {
public void onClickTest(View view);
}
然后在Activity里实现接口。
@Override
public void onClickTest(View view) {
// Snackbar.make(view, "click", Snackbar.LENGTH_LONG)
// .setAction("Action", null).show();
Intent intent = new Intent(this,CustomActivity.class);
startActivity(intent);
}
再后,在代码中set事件进去。
binding.setVariable(BR.handler,this);
最后,看下我们的布局。
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
>
<data>
<variable
name="user"
type="beans.User"/>
<variable
name="handler"
type="events.ClickHandler"/>
</data>
<RelativeLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/content_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="gl.com.databindingdemo.MainActivity"
tools:showIn="@layout/activity_main">
<TextView
android:layout_marginTop="50dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.username}"
android:onClick="@{handler::onClickTest}"
/>
</RelativeLayout>
</layout>
注意@{handler::onClickTest}
,和下面的差别,要注意啦。
哈哈,简单吧。
3.2 监听事件
和上面的类型,不过,我们这里的接口中不在是View,而是其他的东西,比如实体类。我们要在点击的时候保存,这时候怎么办呢?
public interface SaveHandler {
public void saveUser(User user);
}
对应布局文件中的代码变成这样子。
android:onClick="@{()->handler.saveUser(user)}"
各位老司机一定知道,这是啥子了吧。当事件发生的时候,会执行对应的lambda表达式。
关于这两个的区别,这里就不说了。各位大大看这里两者的区别,需烦请
4. 详细说说Layout
通过上面,我们已经了解了DataBinding。但是,还远远不够,接着继续。
- Imports
- Variables
- Includes
- Expression Language
4.1 imports
假如我们想用View.GONE 咋办,如何吧View到进来呢。在 data下面
<import type="android.view.View"/>
其他额外的类也是这样的。
4.2 Variables
<variable
name="user"
type="beans.User"/>
- name 是在xml文件中用的变量名
- type是类型
- 这里也可用一些其他的类型。如List、Map等等
4.3 includes
这里指我们的include标签。在使用include标签的时候要注意。
<include layout="@layout/content_main"
bind:user="@{user}"
bind:handler="@{handler}"
/>
使用bind的方式,把当前的data绑定到include对应的文件。千万要注意了,
4.4 Expression Language
支持如下
暂时部支持:super、this、new操作符。
下面的这一点比较好玩。
android:text="@{user.displayName ?? user.lastName}"
//等于
android:text="@{user.displayName != null ? user.displayName : user.lastName}"
这个是不是很有意思。
集合类的支持
android:text="@{list[index]}"
-
android:text="@{map['firstName']}"
注意 用单引号
资源Resource支持
android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}"
甚至还可以用格式化字符串那套
android:text="@{@string/nameFormat(firstName, lastName)}"
<string name="nameFormat">%s, %s</string>
这 厉害了。
5. 数据的变化如何反应到UI上
要想让数据的变化立马相应在UI上,我们有如下办法。
- Observable Objects
- ObservableFields
- Observable Collections
5.1 Observable Objects
我们的Bean需要继承BaseObservable,并且在set方法中(改变属性)调用notifyPropertyChanged或者notifyChange即可。
5.2 ObservableFields
public final ObservableField<String> userName =
new ObservableField<>();
我们只需要调用set方法改变属性即可。set方法代码如下
public void set(T value) {
if (value != mValue) {
mValue = value;
notifyChange();
}
}
5.3 Observable Collections
同理
我们来看下对应包下有那些,如图
6. 总结
到这里,我们的基础用法学完了,还有一些非常高级的用法还没看到,大家快去尝试下吧,
参考资料
* Android developer
* 大帅的文章