一坏快、描述
MVC,MVP都是大家所熟知的憎夷,而今天的主題的MVVM數(shù)據(jù)綁定莽鸿,這個是最新推出的框架,剛加入公司沒多久拾给,看公司里的同事再用這個富拗,所以我熟悉之后發(fā)現(xiàn)確實(shí)挺好用的,在這里分享給大家鸣戴。
二、引用
Data Binding自從去年的Google I/O發(fā)布到至今粘拾,也有近一年的時間了窄锅。這一年來,從Beta到如今比較完善的版本,從Android Studio 1.3到如今2.1.2的支持入偷,可以說Data Binding已經(jīng)是一個可用度較高追驴,也能帶來實(shí)際生產(chǎn)力提升的技術(shù)了。
而事實(shí)上疏之,真正使用到Data Binding的公司殿雪、項目仍然是比較少的》孀Γ可能是出于穩(wěn)定性考慮丙曙,亦或是對Data Binding技術(shù)本身不夠熟悉,又或許對新技術(shù)沒什么追求其骄。
我司在新的產(chǎn)品中就全面使用了Data Binding技術(shù)亏镰,無論是我,還是新來直接面對Data Binding上手的工程師也好拯爽,都對其愛不釋手索抓,用慣了后簡直停不下來。
希望在看完本文的介紹后毯炮,會有更多的朋友產(chǎn)生興趣逼肯,來使用Data Binding,參與它的討論桃煎。
三篮幢、什么是DataBinding
這里我以我的理解來說,就是一個或者多個實(shí)體對象對應(yīng)著一個頁面备禀,實(shí)體中的某些屬性綁定著頁面上的控件洲拇,當(dāng)屬性的值改變時,頁面上的控件會自動更新數(shù)據(jù)曲尸。
四赋续、效果展示
沒用DataBinding之前
XML布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.junwen.databinding.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="姓名:" />
<TextView
android:id="@+id/activity_main_stu_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="學(xué)生姓名" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="年齡:" />
<TextView
android:id="@+id/activity_main_stu_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="學(xué)生年齡" />
</LinearLayout>
<Button
android:id="@+id/activity_main_stu_setting"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="更改姓名" />
</LinearLayout>
Student實(shí)體類
/**
* 描述:學(xué)生對象
* 作者:卜俊文
* 創(chuàng)建:2016/8/10 10:20
* 郵箱:344176791@qq.com
*/
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
}
MainActivity主頁面
public class MainActivity extends AppCompatActivity {
private TextView tv_name; //學(xué)生姓名
private TextView tv_age; //學(xué)生年齡
private Button btn_setting; //設(shè)置
private Student student; //學(xué)生對象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
initListener();
}
/**
* 描述:初始化控件
* 作者:卜俊文
* 郵箱:344176791@qq.com
* 創(chuàng)建時間: 2016/8/10 10:17
*/
private void initView() {
tv_name = (TextView) findViewById(R.id.activity_main_stu_name);
tv_age = (TextView) findViewById(R.id.activity_main_stu_age);
btn_setting = (Button) findViewById(R.id.activity_main_stu_setting);
}
/**
* 描述:初始化數(shù)據(jù)
* 作者:卜俊文
* 郵箱:344176791@qq.com
* 創(chuàng)建時間: 2016/8/10 10:19
*/
private void initData() {
//創(chuàng)建一個學(xué)生對象
student = new Student("俊文", 22);
//根據(jù)學(xué)生對象賦值到控件上
tv_name.setText(student.getName());
tv_age.setText(String.valueOf(student.getAge()));
}
/**
* 描述:初始化監(jiān)聽
* 作者:卜俊文
* 郵箱:344176791@qq.com
* 創(chuàng)建時間: 2016/8/10 10:22
*/
private void initListener() {
btn_setting.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//點(diǎn)擊設(shè)置,更改Student對象的名字。
student.setName("卜俊文");
tv_name.setText(student.getName());
}
});
}
}
運(yùn)用DataBinding
XML布局
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="student"
type="com.example.junwen.databinding.Student" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="姓名:" />
<TextView
android:id="@+id/activity_main_stu_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="@{student.name}" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="年齡:" />
<TextView
android:id="@+id/activity_main_stu_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="@{String.valueOf(student.age)}" />
</LinearLayout>
<Button
android:id="@+id/activity_main_stu_setting"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="更改姓名" />
</LinearLayout>
</layout>
Student實(shí)體類
/**
* 描述:學(xué)生對象, @Bindable注解是為了能在BR里面找到這個屬性 notifyPropertyChanged(); 這個方法是當(dāng)調(diào)用的時候另患,會通知綁定的控件去改變值
* 作者:卜俊文
* 創(chuàng)建:2016/8/10 10:20
* 郵箱:344176791@qq.com
*/
public class Student extends BaseObservable {
@Bindable
private String name;
@Bindable
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(com.example.junwen.databinding.BR.name);
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
notifyPropertyChanged(com.example.junwen.databinding.BR.age);
}
}
MainActivity主頁面
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding activity_main_binding; //本頁面的Binding對象
private Student student; //學(xué)生對象
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
initListener();
}
/**
* 描述:初始化數(shù)據(jù)
* 作者:卜俊文
* 郵箱:344176791@qq.com
* 創(chuàng)建時間: 2016/8/10 10:48
*/
private void initData() {
//這個就類似于setContentView
activity_main_binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
student = new Student("俊文", 22);
//把Student對象綁定到布局的控件中去,現(xiàn)在開始只要student對象屬性變化纽乱,控件的值也是相應(yīng)改變
activity_main_binding.setStudent(student);
}
/**
* 描述:初始化監(jiān)聽
* 作者:卜俊文
* 郵箱:344176791@qq.com
* 創(chuàng)建時間: 2016/8/10 10:22
*/
private void initListener() {
activity_main_binding.activityMainStuSetting.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
student.setName("卜俊文");
}
});
}
}
五、優(yōu)劣所在昆箕?
優(yōu)勢
(1) DataBinding不需要findviewbyId鸦列,只需要根據(jù)binding對象去查找到對應(yīng)的控件。
(2)直接綁定一個對象到XML布局中鹏倘,當(dāng)對象的屬性變化時薯嗤,布局中的控件會馬上同步變化。
(3)UI代碼放到了xml中纤泵,布局和數(shù)據(jù)更緊密
劣勢
(1)IDE支持還不那么完善(提示骆姐、表達(dá)式)
(2)報錯信息不那么直接
六、開始編寫
(1) 在app / build.gradle 中加入以下字段,即可使用DataBinding框架
dataBinding {
enabled = true
}
(2)編寫XML玻褪,這里給出一個XML模版
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="item"
type="com.example.junwen.databinding.Student" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{item.name}" />
</LinearLayout>
</layout>
此模塊由<Layout>標(biāo)簽作為根節(jié)點(diǎn)肉渴,里面包含兩部分,第一部分是<data>,第二部分就是<LinearLayout>带射,也就類似于以前我們寫布局時的根布局同规。
其中<data>標(biāo)簽中可以聲明對象,變量以及導(dǎo)入包等功能窟社,在這里我導(dǎo)入了Student對象券勺,在下面我需要用到我就可以導(dǎo)入進(jìn)來,并且起成item的一個別名桥爽。
其中<LinearLayout>中朱灿,包含了一個TextView,這個TextView的text屬性值是這樣賦值的(格式必須對):
android:text="@{item.name}"
雙引號中 " @{具體變量或者對象的屬性值}" 钠四,不只這些盗扒,還可以在里面運(yùn)用表達(dá)式,例如上面的例子中的
android:text="@{String.valueOf(student.age)}"
這個能夠在一個屬性的后面添加字符串比如下面
android:text="@{item.progress+`%`}"
(3)編寫MainActivity
(1)取得Binding對象缀去,這個就類似于setContentView()侣灶,返回的對象其實(shí)是一個ViewDataBinding,但是我這里寫的是ActivityMainBinding缕碎,你可以比較一下ActivityMainBinding 和 R.layout.activity_main有什么相似的地方嗎褥影?不錯,就是拼接起來的咏雌,這樣就可以獲得這個頁面的Binding對象凡怎。
ActivityMainBinding activity_main_binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
(2)創(chuàng)建一個Student對象,并且調(diào)用setStudent(student)方法赊抖,這個方法他會自動生成的统倒,實(shí)現(xiàn)了實(shí)體與xml綁定。
Student student = new Student("俊文", 22);
//把Student對象綁定到布局的控件中去,現(xiàn)在開始只要student對象屬性變化氛雪,控件的值也是相應(yīng)改變
activity_main_binding.setStudent(student)
(3)設(shè)置監(jiān)聽房匆,直接通過binding對象查詢到按鈕控件,這個activityMainStuSetting也會自動生成的报亩,如果遇到?jīng)]有生成浴鸿,你需要build一下項目,他就會出來了,執(zhí)行setName方法弦追,在其內(nèi)部就會去通知控件更新文本岳链。
activity_main_binding.activityMainStuSetting.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
student.setName("卜俊文");
}
});
七、其他
操作符示例:
(1)判斷屬性賦值不同的圖片
android:src="@{item.checkState.equals(String.valueOf(3)) ? @drawable/ic_task_exit : @drawable/ic_task_success }"
(2)設(shè)置不同的字符串
android:text='@{error ? "error" : "ok"}'
XML的DataBinding模版XML快速創(chuàng)建
關(guān)于DataBinding數(shù)據(jù)綁定
Android官方數(shù)據(jù)綁定框架DataBinding
從零開始的Android新項目7 - Data Binding入門篇
Android官方數(shù)據(jù)綁定框架DataBinding(一)
Android Data Binding代碼實(shí)戰(zhàn)
八劲件、總結(jié)
在此就總結(jié)了一些基本的DataBind的用法宠页,可能有些地方說的不到位的左胞,也是剛接觸不是很熟悉,就是憑自己的理解來說的举户。
歡迎關(guān)注我的微信公眾號,分享更多技術(shù)文章。