Android數據綁定框架DataBinding

今天介紹一個新框架DataBinding,之前我們需要在每個activity findViewById,不僅麻煩,還增加代碼的耦合性, 而DataBinding省時省力,提高解析XML的速度等等

寫篇文章提提神,不用午睡了.gif

那很多人包括我在內現在用著ButterKnife 或者注解框架 xutils等,其實我個人認為ButterKnife 這個懶人庫還是很不錯的 ,但是與DataBinding想比還是不好用,那其他的第三方框架我認為 如果單單只是用它的注解 確實沒什么必要 現在我們開始普及一下他的用法 :

  • 環境搭建 這是谷歌去年大會上新推出來的 所以你的api 不能太低哦
android {
    ....
    dataBinding {
        enabled = true
    }
}

先說一個基礎的的對象賦值

  • 我還是喜歡在activity 說起,以下就是activity的寫法 不用像之前的setContentView
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.item.main);
        User user1 = new User("sirai", "23");
        binding.setUser(user1);
  • 布局文件 item.main主要的不同 還是展示在layout 布局文件,here沒有給控件定義id,而是用了@{ }的方法
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable
            name="user"
            type="sale.xz.org.databind.User" />
    </data>

    <LinearLayout
        android:layout_width="wrap_content" android:layout_height="40dp"
        android:gravity="center" android:orientation="horizontal" >

        <!--@{user.clickName} 點擊方法-->
        <TextView
            android:layout_width="wrap_content" android:layout_height="wrap_content"
            android:text="@{user.name}"  android:layout_marginLeft="20dp"
            android:onClick="@{user.clickName}" />

        <!--三元表達式 這句話等于  user.age == null ? user.age : user.name-->
        <TextView
            android:layout_width="wrap_content" android:layout_height="wrap_content"
            android:text="@{user.age??user.name}" android:layout_marginLeft="20dp" />

    </LinearLayout>
</layout>
  • 當然了我們要有一個實體類,隨便寫了一個簡單的
public class User {
    private String name;
    private String age;

    public User(String name, String age) {
        this.name = name;
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public String getName() {
        return this.name;
    }

    public String getAge() {
        return this.age;
    }

}

接下來 我們是list 賦值各個不同的layout 頁面,and 賦值adapter

  • activity
  ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    
        User user1 = new User("sirais", "25");
        User user2 = new User("sirai", "23");
        List<User> list1 = new ArrayList<User>();
        list1.add(user2);
        list1.add(user1);
        binding.setUsers(list1);

//adapter listview 賦值
      List<User> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            User user = new User("sirai"+i+"", "23");
            list.add(user);
        }
        CommonAdapter<User> adapter = new CommonAdapter<>(this, list, R.layout.item_main, sale.xz.org.databind.BR.user);
        binding.setAdapter(adapter);

  • 布局文件 activity_main 其中有兩個include 不及 需要提示注意的是app xml命名空間
<layout xmlns:android="http://schemas.android.com/apk/res/android"  xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>

        <import type="java.util.ArrayList" />
        <variable
            name="users"
            type="java.util.List<User>"/>

        <variable
            name="adapter"
            type="android.widget.BaseAdapter"/>
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <include
            layout="@layout/item_main"
            app:user="@{ users[0] }"/>

        <include
            layout="@layout/item_main"
            app:user="@{ users[1] }"/>


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal">

            <!--所有的set方法都可以用app-->
            <ListView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:adapter="@{ adapter }"/>

        </LinearLayout>
    </LinearLayout>
</layout>
  • 嗯嗯 這里就說到了 我們的adapter 這里用了BR文件,BR文件和R文件都是系統會自動生成的,只是R文件用于資源的id
public class CommonAdapter<T> extends BaseAdapter {
    private Context context;//上下文環境
    private List<T> list;//通用的,不知道數據
    private int layoutId;//通用的,不知道布局
    private int variableId;//變量的id

    /**
     * 構造方法
     */
    public CommonAdapter(Context context, List<T> list, int layoutId, int variableId) {
        this.context = context;
        this.list = list;
        this.layoutId = layoutId;
        this.variableId = variableId;
    }

    @Override
    public int getCount() {
        if (list != null)
            return list.size();
        return 0;
    }

    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewDataBinding binding = null;
        if (convertView == null) {
            binding = DataBindingUtil.inflate(LayoutInflater.from(context), layoutId, parent, false);
        } else {
            binding = DataBindingUtil.getBinding(convertView);
        }
        binding.setVariable(variableId, list.get(position));
        return binding.getRoot();
    }
}
  • 最后再說明一下實際運用中肯定也會有很多的點擊事件,那么如何實現點擊事件的呢?怎么刷新變量呢?

    • 這就是我們為什么在User實體類User中添加了clickName方法的原因

    • 刷新變量 這里用到一個觀察者模式,只需要把User繼承BaseObservable類,并且在要更改的屬性上加一個@Bindble,再在setName方法中加入notifyPropertyChanged這樣一句話則可。

public class User extends BaseObservable {
    private String name;
    private String age;

    public User(String name, String age) {
        this.name = name;
        this.age = age;
    }

    public void setAge(String age) {
        this.age = age;
    }
    
    public String getAge() {
        return this.age;
    }



    public void clickName(View view){
        setName(getName() + "( 已點擊 )");
    }

    @Bindable
    public String getName() {
        return name;

    }

    public void setName(String name) {
        this.name = name;
        //刷新變量(變量id)
        notifyPropertyChanged(sale.xz.org.databind.BR.name);
    }


}
賦值adapter效果圖.jpg
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,048評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,414評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,169評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,722評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,465評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,823評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,813評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,000評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,554評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,295評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,513評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,722評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,125評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,430評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,237評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,482評論 2 379

推薦閱讀更多精彩內容