我先說一下我公司的情況,然後再說對android databinding的認識
記得去年6月份,我們公司開發的項目(主要是針對餐飲的)走進了市場,遇到了一些問題。客戶都說我們產品雖然有一定的好處,但不夠便捷,如果能有一個點餐系統來配合使用,一定會更好的。
公司一直遵循客戶是上帝,於是苦逼的工作自然就落到了我們開發部的頭上了。於是就收集資料,模仿別人現有的產品----食通天,根據別人的成熟產品,自己定需求,定好需求,設計好數據庫,接下來的時間就是考慮要用什麼語言來開發了,於是在領導的光明指導下,說“那就用C#”來開發吧!
按理說,使用什麼語言來開發都是沒有什麼問題的,誰叫咱是開發部呢?可是現在面臨着這麼一個問題,我們部門比較小,總人數就10人,其中包括3個測試,3個java,1個安卓,1個iOS,一個UI,一個項目經理,一個產品經理。另外,測試、UI、產品經理、項目經理是不進行開發的。那就僅剩3個java和1個android、1個iOS了。有沒有發現什麼?沒錯,我們都不是做C#的,沒有一個人接觸過C#,於是iOS走了,項目經理也走了。那隻能剩下苦逼的我android和3個java了。於是就學唄,用一個星期的時間瞭解了C#,發現C#其實跟java差不多,語法基本都一樣,容易理解。好吧,懂得基本情況,就開發唄!
好吧,開幹!!在進行點餐系統的開發過程中,我發現了一個在android領域中還沒有引入的框架:MVVM。對,你沒有看錯,就是MVVM,它是一種採用數據綁定的一種開發模式,可以完美的把視圖xaml、數據、業務邏輯進行完美的解耦。這個點餐系統的項目,完美經歷了4個月的加班加班加班,終於完工了,但整個項目所使用到的技術中給我印象最深刻的是C#的數據綁定這模塊,自此,我對數據綁定有了初步的概念。
好了,閒話已經說了不少了,開始說說我們的android吧
去年的Google IO 大會上,Android 團隊發佈了一個數據綁定框架(Data Binding Library) 。以後可以直接在 layout 佈局 xml 文件中綁定數據了,無需再 findViewById 然後手工設置數據了。其語法和使用方式和 JSP 中的 EL 表達式非常類似。但由於,可能當時我在做C#開發,無暇顧及android的情況,直到今年初,我沒有那麼忙時,才發現了android已經開始可以使用數據綁定了。
那麼,在android上如何使用databinding的呢?
使用步驟(開發工具android studio):
1.配置buid.grade文件
2.定義數據實體
3.佈局文件中聲明實體,綁定控件
4.java代碼引用,填充實體
1.配置buid.grade文件。在module的android下添加如下代碼:
dataBinding{
enabled=true
}
2.定義數據實體
package com.example.databinding.bean;
/**
* Created by h on 2016/9/8.
*/
public class User{
private String name;
private int 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;
}
}
3.佈局文件中聲明實體,綁定控件
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="user"
type="com.example.databinding.bean.User"/>
</data>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.name}"
/>
</LinearLayout>
</layout>
4.java代碼引用,填充實體
package com.example.databinding;
import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.example.databinding.bean.User;
import com.example.databinding.bean.ViewModel;
import com.example.databinding.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
User user=new User();
user.setName("huangxuanheng is very good");
binding.setUser(user);
}
}
上述代碼運行後,效果如下圖:
![效果圖1](https://img-blog.csdn.net/20160909110732918)
小結:
在佈局文件中,根節點是layout,如果要綁定數據實體,則要在data節點下聲明,data節點下的variable節點,就是用來聲明所有引用的數據實體對象和類別的,其中name屬性是聲明對象實例,type屬性聲明對象類型,控件中要想引用data中聲明的實體對象,可以通過@{對象.屬性}引用,如上例中的TextView關於text屬性的聲明 android:text="@{user.name}"
此時,如果實體對象的屬性值發生了改變,界面會不會改變呢?答案是否定的,但實際工作中,我們往往有這樣的需求:實體對象的屬性改變了,界面也要跟着改變,此時,應該怎麼做呢?
android裏面提供了一個非常好的一個類BaseObservable,只需要實體類基礎了該類,並且在屬性發生改變的時候,notify一下,獲取屬性的方法上標明註解 @Bindable,就可以通知到界面改變了,大致代碼如下:
public class User extends BaseObservable {
private String name;
private int age;
@Bindable
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
}
@Bindable
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
notifyPropertyChanged(BR.age);
}
}
BR不用理它是什麼,個人認爲相當於R文件中的R,自動生成的,意思是提醒界面改變對應的屬性值
android的數據綁定通知方面,感覺是有點複雜的,通過以上這種方式可以達到單向通知界面。在C#的開發過程中,我發現裏面的數據綁定的定義非常簡單方便,並且關於雙向綁定的定義也是非常簡單的,只需在xaml文件裏面定義,就可以輕鬆的實現雙向綁定了。so~!這方面還有待android進行優化
開發中,往往涉及到點擊事件,關於點擊事件以往的做法,都是通過findViewById,然後再setOnClickListener實現的,現在有了databinding,關於findViewById的事,自然就不會再用了,那要怎麼做呢?
其實很簡單,使用規則跟實體綁定類似的,只需在一個類裏面編寫一個點擊的方法,然後在佈局中data節點下,新增該類型的對象,在控件的onClick屬性中調用該方法就可以瞭如: android:onClick="@{activity.onTxClick}",示例代碼如下:
佈局:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="user"
type="com.example.databinding.bean.User"/>
<variable
name="activity"
type="com.example.databinding.MainActivity"/>
</data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:layout_centerInParent="true"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="36sp"
android:text="@{user.name}"
android:onClick="@{activity.onTxClick}"/>
</RelativeLayout>
</layout>
activity:
package com.example.databinding;
import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.example.databinding.bean.User;
import com.example.databinding.bean.ViewModel;
import com.example.databinding.databinding.ActivityMainBinding;
public class MainActivity extends AppCompatActivity {
ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
User user=new User();
user.setName("huangxuanheng is very good");
binding.setUser(user);
binding.setActivity(this);
}
public void onTxClick(View view){
Toast.makeText(this,"ni hao a ",Toast.LENGTH_SHORT).show();
User user = binding.getUser();
user.setName("huangxianheng you are a good man!");
}
}
搞定,此時點擊後,就可以看到彈出吐司了
以上就是我對android databinding的初步認識,採用了MVVM框架,可以很好的將業務和視圖進行解耦。有了databinding,android技術上將更上一層樓,但目前還在不斷的改進,API可能隨時有改動,使用時切莫要謹慎了!