1. DataBinding使用
build.gradle中添加
dataBinding {
enabled true
}
2. 创建JavaBean对象
public class User extends BaseObservable{
private String name;
private String phone;
public int isHandSome;
public User(String name,String phone){
this.name = name;
this.phone = phone;
}
@Bindable
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
}
@Bindable
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
notifyPropertyChanged(BR.phone);
}
}
3.创建布局文件
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View"/>
<import type="java.util.ArrayList"/>
<import type="java.util.Map"/>
<variable
name="user"
type="com.zlc.mvvm.User"/>
<variable
name="age"
type="String"/>
<variable
name="list"
type="ArrayList<String>"/>
<variable
name="map"
type="Map<String,String>"/>
<variable
name="handler"
type="com.zlc.mvvm.EventHandler"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
<TextView
android:id="@+id/id_tv1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{user.name}"
android:paddingBottom="10dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{age}"
android:layout_marginTop="10dp"/>
<TextView
android:id="@+id/id_tv3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{user.isHandSome == 0 ? @string/hand1 : @string/hand2}"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"/>
<include layout="@layout/phone_layout"
bind:user="@{user}"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{list[1]}"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text='@{map["name"]}'
android:layout_marginBottom="10dp"
android:onClick="@{handler.handOnClick}"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点我点我"
android:onClick="@{handler.handOnClick}"/>
</LinearLayout>
</layout>
4.简单赋值使用
新建变量值 user 导入User类型
<variable
name="user"
type="com.zlc.mvvm.User"/>
<TextView
android:id="@+id/id_tv1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{user.name}"
android:paddingBottom="10dp"/>
代码中使用
ActivityMainBinding dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
User user = new User("zlc","18684732678");
user.isHandSome = 0;
dataBinding.setUser(user);
5.变量赋值
<variable
name="age"
type="String"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{String.valueOf(age)}"
android:layout_marginTop="10dp"/>
dataBinding.setAge(25);
6. inclue加载布局
两个布局里面都需要有
<variable
name="user"
type="com.zlc.mvvm.User"/>
新布局
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="user"
type="com.zlc.mvvm.User"/>
</data>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/id_tv2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{user.phone}"/>
</LinearLayout>
</layout>
<include layout="@layout/phone_layout"
bind:user="@{user}"/>
7. 引用资源文件的值
<resources>
<string name="app_name">MVVMProject</string>
<string name="hand1">帅</string>
<string name="hand2">帅而且有钱</string>
</resources>
<TextView
android:id="@+id/id_tv3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{user.isHandSome == 0 ? @string/hand1 : @string/hand2}"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"/>
8. import导入
<import type="android.view.View"/>
<TextView
android:id="@+id/id_tv3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hand2}"
android:visibility="@{user.isHandSome == 0 ? View.VISIBLE : View.GONE}""
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"/>
9. List集合使用
<import type="java.util.ArrayList"/>
不能出现< 用<替代
<variable
name="list"
type="ArrayList<String>"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{list[1]}"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"/>
ArrayList list = new ArrayList();
list.add("哈哈哈");
list.add("嘻嘻嘻");
list.add("呵呵呵");
dataBinding.setList(list);
10. Map集合使用
<import type="java.util.Map"/>
<variable
name="map"
type="Map<String,String>"/>
//根据key取value
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text='@{map["name"]}'
android:layout_marginBottom="10dp"
android:onClick="@{handler.handOnClick}"
/>
Map map = new HashMap();
map.put("name","hhhzlc");
dataBinding.setMap(map);
11. 事件绑定
public void onClick(View view){
user.setName("郑乐成");
user.setPhone("18888888888"); Toast.makeText(this,"zqwxhni",Toast.LENGTH_LONG).show();
}
<variable
name="click"
type="com.zlc.mvvm.MainActivity"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点我点我"
android:onClick="@{click.onClick}"/>
dataBinding.setClick(this);
12. 通过Observable的方式去通知UI数据已经改变
官方为我们提供了更加简便的方式BaseObservable,我们的实体类只需要继承该类,稍做几个操作,就能轻松实现数据变化的通知。如何使用呢? 首先我们的实体类要继承BaseObservale类,第二步在Getter上使用注解@Bindable,第三步,在Setter里调用方法notifyPropertyChanged,第四步,完成
package com.zlc.mvvm;
import android.databinding.BaseObservable;
import android.databinding.Bindable;
/**
* Created by Administrator on 2017/10/21.
*/
public class User extends BaseObservable{
private String name;
private String phone;
public int isHandSome;
public User(String name,String phone){
this.name = name;
this.phone = phone;
}
@Bindable
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
}
@Bindable
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
notifyPropertyChanged(BR.phone);
}
}
public void onClick(View view){
user.setName("郑乐成");
user.setPhone("18888888888");
Toast.makeText(this,"zqwxhni",Toast.LENGTH_LONG).show();
}
dataBinding.setClick(this);
13. Inflate
ViewDataBinding binding = DataBindingUtil.inflate(inflate,layoutId,viewGroup,attachToParent);
View view = inflate.getRoot(); //获取view对象
14. DataBinding VS RecyclerView VS ListView
item布局
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="user"
type="com.zlc.mvvm.User" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:gravity="center_vertical">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@{user.name}"
android:layout_alignParentLeft="true"
android:gravity="center"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@{user.phone}"
android:layout_alignParentRight="true"
android:gravity="center"/>
</LinearLayout>
</layout>
适配器
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder>{
private ArrayList<User> mData;
private Context mContext;
public MyAdapter(Context context, ArrayList<User> data) {
this.mContext = context;
this.mData = data;
}
@Override
public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ViewDataBinding binding = DataBindingUtil.inflate(LayoutInflater.from(mContext), R.layout.list_item, parent, false);
MyHolder holder = new MyHolder(binding.getRoot());
holder.setBinding(binding);
return holder;
}
@Override
public void onBindViewHolder(MyHolder holder, int position) {
holder.getBinding().setVariable(BR.user,mData.get(position));
holder.getBinding().executePendingBindings();
}
@Override
public int getItemCount() {
return mData.size();
}
public class MyHolder extends RecyclerView.ViewHolder{
private ViewDataBinding binding;
public MyHolder(View itemView) {
super(itemView);
}
public void setBinding(ViewDataBinding binding) {
this.binding = binding;
}
public ViewDataBinding getBinding() {
return binding;
}
}
}
15.自定义setter(BindingAdapter)
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data class=".Custom">
<variable
name="imageUrl"
type="String" />
</data>
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:imageUrl="@{imageUrl}"/>
</layout>
binding.setImageUrl("http://images.csdn.net/20150810/Blog-Image%E5%89%AF%E6%9C%AC.jpg");
@BindingAdapter({"bind:imageUrl"})
public static void imageLoader(ImageView imageView, String url) {
ImageLoaderUtils.getInstance().displayImage(url, imageView);
}
16. Converters
Converter是什么呢?举个例子吧:假如你的控件需要一个格式化好的时间,但是你只有一个Date类型额变量咋办?肯定有人会说这个简单,转化完成后在设置,恩,这也是一种办法,但是DataBinding还给我们提供了另外一种方式,虽然原理一样,但是这种方式使用的场景更多,那就是——Converter
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data class=".Custom">
<variable
name="time"
type="java.util.Date" />
</data>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@{time}"/>
</layout>
binding.setTime(new Date());
@BindingConversion
public static String convertDate(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(date);
}