Android Databinding介绍
官方介绍地址:http://developer.android.com/intl/zh-cn/tools/data-binding/guide.html
前言
相信开发过Android的都知道findViewById,也自然知道它是多么枯燥,整个Activity有很大一部分被它所占据,到后来通过依赖注入框架(ButterKnife和Xuils3等),虽然说极大的减少了原来的findViewById的方法,但是依然需要定义一大堆view来执行绑定数据等操作。2015年 Google IO大会带来的Data Binding库可以方便的实现MVVM架构模式,使用它可以改善应用程序开发,使代码更简洁。
在这里先说说Android开发模式的变化,从原先所有的代码写在Acitvity到模仿后台开发的MVC。再到后来的MVP模式,MVP即是(model–处理业务逻辑(主要读写数据或者与后台通信)、view处理ui控件、presenter-控制器,操作model和view),它虽然可以极大体现模块化、以及各个模块的功能特性,但是在实际的操作中, 会使项目多了很多不同的类,要实现一个基础的MVP的功能,至少需要五个类+Activity来实现,极大的增加代码量。到现在MVVM框架,MVVM实际上只有三层,Model,ViewModel,View,View与ViewModel实现了双向绑定(这也是此框架最大的特点),也就是界面上的改变会直接影响到后台代码的改变,后台数值的改变后可直接影响到界面的数据显示,ViewModel与Model实现双方向的交互,下面则是对Data Binding框架的简单使用的介绍。
一、开发环境搭建
Data binding只支持Android Studio的开发,Android Studio的版本必须在1.3版本及以上,Gradle在1.2.3以上,BuildToolsVersion必须在22.0.1以上。以上条件达到以后,只需再项目的build.gradle文件中的android节点下增加以下代码使项目支持Databinding,这样的话就可以使用这个框架了。
dataBinding {
enabled true
}
二、工作原理
DataBinding开发实际上与原始的Android开发没有过多的区别,只是极大的简化了代码对控件的操作,允许程序员直接在布局上进行数据的赋值,我们只需要在代码中对布局中的文件变量进行赋值操作,操作之后界面便会实现相应的改变。我们需要做的改变只是将布局文件的根布局改为,layout节点下有data和真正的layout节点(也就是LinearLayout等布局方式),下面看一段简单的代码:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fresco="http://schemas.android.com/apk/res-auto">
<data>
<import type="wshuttle.com.testmvvm.bean.UserInfo"/>
<variable name="userInfo" type="UserInfo" ></variable>
<variable
name="myEventHandler"
type="wshuttle.com.testmvvm.ui.MainActivity.MyEventHandler"></variable>
<variable
name="orderInfo"
type="wshuttle.com.testmvvm.bean.OrderInfo" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true"
android:clipToPadding="false"
android:background="@color/bg_color"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="@+id/toolbar"
android:background="@color/theme_color">
</android.support.v7.widget.Toolbar>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/text_color"
android:text="@{String.valueOf(userInfo.id)}" />
<EditText
android:cursorVisible="true"
android:textCursorDrawable="@drawable/color_cursor"
android:layout_width="match_parent"
android:textColor="@color/text_color"
android:id="@+id/username"
android:layout_height="wrap_content"
android:text="@={userInfo.name}" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/text_color"
android:text="@={userInfo.type}" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/text_color"
android:visibility="@{show.get()?View.VISIBLE:View.GONE}"
android:onClick="@{(view) ->myEventHandler.getUser(userInfo)}"
android:id="@+id/btnGetName"
android:text="获取用户信息" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/text_color"
android:visibility="@{show.get()?View.VISIBLE:View.GONE}"
android:onClick="@{myEventHandler::onClick}"
android:id="@+id/btnGetType"
android:text="获取车主姓名" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/text_color"
android:text="@{orderInfo.orderid}" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/text_color"
android:text="@{orderInfo.rescueName}" />
</LinearLayout>
</layout>
以上代码是data binding的xml的简单实现,在这里不具体进行讲解,在之后的文章会进行细致分析,只需稍微记住xml文件有之前layout文件的不同之处即可。看完data binding的布局文件,自然需要再看看它的activity文件了,下面是上面代码对应的activity及实体类:
MainActivity
package wshuttle.com.testmvvm.ui;
import android.Manifest;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.databinding.DataBindingUtil;
import android.databinding.ObservableBoolean;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.support.v4.app.ActivityCompat;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Toast;
import com.blueberry.compress.ImageCompress;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import wshuttle.com.testmvvm.BR;
import wshuttle.com.testmvvm.R;
import wshuttle.com.testmvvm.adapter.BaseListViewAdapter;
import wshuttle.com.testmvvm.adapter.BaseRecycleViewAdapter;
import wshuttle.com.testmvvm.bean.OrderInfo;
import wshuttle.com.testmvvm.bean.UserInfo;
import wshuttle.com.testmvvm.databinding.ActivityMainBinding;
/**
* MVVM:@{},@={},data import variable Event(事件返回值相同即可)
*/
public class MainActivity extends BaseActivity {
public ObservableBoolean show = new ObservableBoolean();
private OrderInfo orderInfo;
ActivityMainBinding bing;
BaseRecycleViewAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
bing = DataBindingUtil.setContentView(this, R.layout.activity_main);
Toolbar toolbar = bing.toolbar;
setSupportActionBar(toolbar);
toolbar.setTitle("ToolBar");
toolbar.setTitle("Use");
bing.setUserInfo(new UserInfo());
bing.setMyEventHandler(new MyEventHandler());
orderInfo = new OrderInfo("20160922142752","曹操");
bing.setOrderInfo(orderInfo);
bing.setImageUrl(R.drawable.ic_launcher);
handler.postDelayed(new Runnable() {
@Override
public void run() {
orderInfo.setOrderid("ABCDEFGHIJK");
orderInfo.setRescueName("刘备");
}
},3000);
}
}
UserInfo
package wshuttle.com.testmvvm.bean;
import android.databinding.ObservableField;
import android.databinding.ObservableInt;
/**
* Observable数据基本类型实现绑定@{}:单向绑定,@={}双向绑定,不是String类型实现双向绑定无法绑定,待解决.
* Created by yzy on 2016/9/21.
*/
public class UserInfo{
public ObservableInt id = new ObservableInt();
public ObservableField<String> name = new ObservableField<String>();
public ObservableField<String> type = new ObservableField<String>();
@Override
public String toString() {
return "UserInfo{" +
"id=" + id.toString() +
", name=" + name.toString() +
", type=" + type.toString() +
'}';
}
public UserInfo(int id, String name, String type) {
this.id.set(id);
this.name.set(name);
this.type.set(type);
}
public UserInfo() {
}
}
OrderInfo
package wshuttle.com.testmvvm.bean;
import android.databinding.BaseObservable;
import android.databinding.Bindable;
import wshuttle.com.testmvvm.BR;
/**
* BR改变数据源,实现绑定@{}:单向绑定,@={}双向绑定
* Created by yzy on 2016/9/22.
*/
public class OrderInfo extends BaseObservable {
private String orderid;
private String rescueName;
public OrderInfo(String orderid, String rescueName) {
this.orderid = orderid;
this.rescueName = rescueName;
}
@Bindable
public String getOrderid() {
return orderid;
}
public void setOrderid(String orderid) {
this.orderid = orderid;
notifyPropertyChanged(BR.orderid);
}
@Bindable
public String getRescueName() {
return rescueName;
}
public void setRescueName(String rescueName) {
this.rescueName = rescueName;
notifyPropertyChanged(BR.rescueName);
}
}
该例子实现的只是简单的双向绑定数据以及在布局中为按钮设置单击事件,实现了三秒更改orderInfo的数据,更新orderInfo实体数据后,界面上绑定数据的位置显示也变成新设置的数据。userinfo的绑定实现了双向绑定、orderinfo则只是单向绑定(数据更改后界面改变)。
三、总结
在本篇文章中,只是简单介绍了data binding的用处以及一个代码的示例,在以后的章节中我们将分成layout,activity,查漏等几大模块来对data binding的具体的讲解,还望多多支持-.-,以下是下一个章节Android databinding详解(一)–layout解析。