GOOGLE IO 2015提供了好多有趣的东西,DataBinding就是其中一个新玩意。毕竟是官方原生支持的MVVM,咱一定要学习一下。
本文通过LyndonChin的MasteringAndroidDataBinding这个项目,系统的学习一下DataBinding
应该说这个还是很简单的,我们还是一步一步来
1.首先配置一下gradle,在系统的gradle里面配置
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
classpath 'com.android.databinding:dataBinder:1.0-rc0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
添加classpath ‘com.android.databinding:dataBinder:1.0-rc0’
随后在app的build.gradle里面配置
apply plugin: 'com.android.application'
apply plugin: 'com.android.databinding'
添加apply plugin: ‘com.android.databinding’
配置就简单的完成了
2.随后我们建立POJO类,非常简单的POJO
public class User {
String name="";
int age=0;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
然后我们看xml
<layout xmlns:android="http://schemas.android.com/apk/res/android" >
<data>
<variable
name="user"
type="com.renyu.databindingdemo.model.User">
</variable>
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView android:text="@{user.name}" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
</layout>
这边简单介绍一下,这边data就是提供数据传递到UI的桥梁。这边根节点一定要是layout,原来的根节点RelativeLayout跟data处在同一子节点上。variable就是真正绑定的地方,type指定了数据对象,使用时候就用name=”user”,我们这边在textview中显示User对象的name字段:@{user.name}
3.最后看看Java中的使用
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding=DataBindingUtil.setContentView(this, R.layout.activity_main);
User user=new User();
user.setAge(1);
user.setName("renyu");
binding.setUser(user);
}
把user对象跟UI关联起来。其中ActivityMainBinding这个是系统生成的,你每在data中创建一个variable,就多了一个set对象
结果就不演示了,就一个textview里面显示值而已
4.见识一下include。include使用时候有个注意点,就是一定要在根节点的viewGroup中使用。看看xml上面有何不同
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="user"
type="com.renyu.databindingdemo.model.User">
</variable>
<variable
name="contact"
type="com.renyu.databindingdemo.model.Contact">
</variable>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView android:text="@{user.name}" android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<include
layout="@layout/view_contact"
bind:contact="@{contact}">
</include>
</LinearLayout>
</layout>
bind:contact定义一个属性,传递刚才的contact实体。
view_contact部分跟之前最初定义一样
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="contact"
type="com.renyu.databindingdemo.model.Contact">
</variable>
</data>
<LinearLayout
android:orientation="vertical" android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:text="@{contact.mail}"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</layout>
java部分也没什么好说的了,也是多绑定一个对象而已
5.java数据类型传递
我们这边仅仅简单的演示下ArrayList、HashMap、int、String
<import type="java.util.HashMap"></import>
<variable
name="map"
type="HashMap<String, String>">
</variable>
<variable
name="key"
type="String">
</variable>
<import type="java.util.ArrayList"></import>
<variable
name="list"
type="ArrayList<String>">
</variable>
<variable
name="index"
type="int">
</variable>
java.lang.*下面的包会被自动导入,其他还是要import声明下
使用时候还是要像数组一样使用
<TextView
android:text="@{map[key]}"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:text="@{list[index]}"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
java部分还是依然绑定
HashMap<String, String> map=new HashMap<>();
map.put("key1", "one");
map.put("key2", "two");
map.put("key3", "three");
map.put("key4", "four");
binding.setMap(map);
binding.setKey("key3");
ArrayList<String> lists=new ArrayList<>();
lists.add("A");
lists.add("B");
lists.add("C");
lists.add("D");
lists.add("E");
binding.setList(lists);
binding.setIndex(1);
6.看看怎么配合资源文件一起使用
<TextView
android:text="@{large?@string/hello_world:@string/action_settings}"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
定义一个large对象,用表达式体现出来
7.看看怎么直接使用控件
我们之前会通过注解的方式,比如butterKnife,现在直接这个就简单了
binding.demoImage.setImageResource(R.mipmap.ic_launcher);
直接activityMainBinding对象就能直接找到我们在xml中定义的id对象,是不是很方便
8.单向绑定
目前仅仅支持从ViewModel到view的数据传递过程,要想实现数据刷新,得注册一个Observable,那么这边POJO定义的跟之前就有一些区别了
public class Brand extends BaseObservable {
String name="";
String image="";
@Bindable
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
}
@Bindable
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
notifyPropertyChanged(BR.image);
}
}
POJO继承了BaseObservable,这个类似观察者模式,并且在每一个get方法中加了@Bindable 注解,在每一个set中加了notifyPropertyChanged。
这块具体代码我没有详看,就直接看了MasteringAndroidDataBinding的描述,这边仅仅总结下:使用@Bindable 去在BR创建一个entry,在发生值改变时候通过notifyPropertyChanged去通知修改
这样在使用时候仅需要修改对象值,brand.setName(“brand_renyu”);就可以在页面中直接完成修改了
再介绍一个方法,我们刚才是定义了一个BaseObservable对象,如果我项目中一开始没有这么写,现在仅仅需要一个变量发生改变,这时候,我们就需要将变量定义成ObservableField< T >或者ObservableInt等这种类型,然后其他都不需要做
public class Group {
public ObservableField<String> groupName=new ObservableField<>();
public ObservableInt groupNum=new ObservableInt();
}
使用时候直接set就可以了
group.groupName.set("GROUPNAME");
9.动态绑定
之前给大家介绍的都是xml写好,直接通过DataBindingUtil.setContentView,然后去赋值或者修改。现在再来看看如何动态加载
那篇文章是使用RecyclerView去实现的,我们这边简单点,直接把view放到一个viewGroup里面去
main_root= (LinearLayout) findViewById(R.id.main_root);
ViewDataBinding binding1=DataBindingUtil.inflate(LayoutInflater.from(this), R.layout.item_recyclerview, main_root, true);
User user1=new User();
user1.setName("gy");
user1.setAge(0);
binding1.setVariable(com.renyu.databindingdemo.BR.user, user1);
binding1.executePendingBindings();
这边直接通过DataBindingUtil.inflate在将view绑定上去,指明数据是BR.user,传递值user1进去,然后执行绑定
10.自定义属性Attribute setters
11.转换器Converters
这两者我就不说明了,因为我觉得在自定义属性时候故意不写attrs或者故意把数据格式传错,这样的程序有碍读者去阅读,没事你要这么做干嘛
至此,AndroidDataBinding就简单的学习了一下,欢迎大家共同讨论