Android Data Binding学习

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&lt;String, String>">

</variable>
<variable
    name="key"
    type="String">

</variable>

<import type="java.util.ArrayList"></import>
<variable
    name="list"
    type="ArrayList&lt;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就简单的学习了一下,欢迎大家共同讨论

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页