android黑科技——完美解決界面邏輯的數據框架DataBinding(最新)的使用(二)

昨天咱們一塊兒學習了dataBinding的基礎用法,我想你可能還停留在它只是不用再findViewById,其實否則,今天咱們就來擴展延伸,看看這個框架到底有什麼魔力讓谷歌官方大力推崇。這裏還沒看昨天的基礎運用的須要去看一看,附上連接:http://www.cnblogs.com/liushilin/p/5681473.htmlhtml

項目已經同步至github:https://github.com/nanchen2251/databindingjava

昨天咱們解決了簡單的使用以及在xml中進行屬性的變換和一些簡單的表達式放在xml文件中的使用問題,你們確定有所疑問,咱們在實際開發中確定會用到不少的佈局重用等,那麼在這個框架中能否一樣作到呢?另外,若是咱們想用這個框架實現圖片加載呢?你們都知道圖片在xml中只能經過src設置本地圖片,並無提供經過url設置的屬性,別急,樓主會把這個方法分享給你。android

1)首先把昨天的xml代碼放到一個獨立的xml文件中,樓主這裏叫user_layout.xml,這裏設置圖片經過使用app自定義屬性設置圖片urlgit

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <layout
 3     xmlns:android="http://schemas.android.com/apk/res/android"
 4     xmlns:tools="http://schemas.android.com/tools"
 5     xmlns:app="http://schemas.android.com/apk/res-auto">
 6     <data>
 7         <variable
 8             name="user"
 9             type="com.example.nanchen.databindingdemo.User">
10         </variable>
11     </data>
12 
13     <LinearLayout
14         android:layout_width="0dp"
15         android:layout_weight = "1"
16         android:layout_height="match_parent"
17         android:gravity="center"
18         android:orientation="vertical"
19         tools:context="com.example.nanchen.databindingdemo.MainActivity">
20 
21         <ImageView
22             android:layout_width="100dp"
23             android:layout_height="100dp"
24             app:imageUrl="@{ user.icon }"/>
25 
26         <TextView
27             android:layout_width="wrap_content"
28             android:layout_height="wrap_content"
29             android:textSize="25sp"
30             android:onClick="@{user.clickName}"
31             android:textColor="@{user.vip? 0xffff0000:0xff000000}"
32             android:text="@{user.nickName + `(` + user.name +`)`}"/>
33 
34         <TextView
35             android:layout_width="wrap_content"
36             android:layout_height="wrap_content"
37             android:textSize="25sp"
38             android:onLongClick="@{user.longClickNickName}"
39             android:text="@{user.nickName ?? user.name}"/>
40 
41         <TextView
42             android:layout_width="wrap_content"
43             android:layout_height="wrap_content"
44             android:textSize="25sp"
45             android:textColor="@{user.level &lt; 3 ? 0xff03bbf9 : 0xfff60bdb }"
46             android:text="@{user.email}"/>
47     </LinearLayout>
48 </layout>

2)而後修改主頁面的xml文件,activity_main.xml,因爲咱們使用的是左右對稱顯示兩個用戶,因此咱們應該用list,而不是以前的user,其中用到的尖括號用轉義方法上一節已經講過。github

<?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"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <!--<variable-->
            <!--name="user"-->
            <!--type="com.example.nanchen.databindingdemo.User">-->
        <!--</variable>-->

        <import type="com.example.nanchen.databindingdemo.User"/>
        <variable
            name="users"
            type="java.util.List&lt;User&gt;"/>
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="horizontal"
        tools:context="com.example.nanchen.databindingdemo.MainActivity">

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

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

 

3)再改下Activity的代碼網絡

package com.example.nanchen.databindingdemo;

import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

import com.example.nanchen.databindingdemo.databinding.ActivityMainBinding;

import java.util.ArrayList;
import java.util.List;


public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        setContentView(R.layout.activity_main);

        ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
        User user = new User();
        user.setName("劉世麟");
        user.setNickName("南塵");
        user.setEmail("liushilin@qq.com");
        user.setVip(true);
        user.setLevel(5);
        user.setIcon("http://qlogo1.store.qq.com/qzone/503233512/503233512/100?1311741184");
//        binding.setUser(user);

        User user1 = new User();
        user1.setName("春春兒");
        user1.setNickName(null);
        user1.setVip(false);
        user1.setEmail("nanchen@qq.com");
        user1.setLevel(1);
//        binding.setUser(user1);

        List<User> list = new ArrayList<>();
        list.add(user);
        list.add(user1);
        binding.setUsers(list);
//        binding.setUser(new User("劉世麟","南塵","liushilin@qq.com"));
    }
}

看看運行效果app

 

看到這裏,也許小夥伴會說,切,不就一個include嗎,這個框架仍是沒帶來飛通常的感受,別急,還有更厲害的使用ListView之類的等着你框架

咱們來看看listView如何實現。ide

1)天然須要先定義一個list_item.xml,用於基本Item的佈局。佈局

 1 <?xml version="1.0" encoding="utf-8"?>
 2 
 3 <layout
 4     xmlns:android="http://schemas.android.com/apk/res/android"
 5     xmlns:app="http://schemas.android.com/apk/res-auto">
 6     
 7     <data>
 8         <variable
 9             name="user"
10             type="com.example.nanchen.databindingdemo.User"/>
11     </data>
12 
13     <LinearLayout
14         android:layout_width="match_parent"
15         android:layout_height="match_parent"
16         android:orientation="horizontal"
17         android:onClick="@{ user.click }">
18         
19         <ImageView
20             android:layout_width="100dp"
21             android:layout_height="100dp"
22             app:imageUrl="@{user.icon}"/>
23 
24         <TextView
25             android:layout_width="match_parent"
26             android:layout_height="match_parent"
27             android:text="@{user.name}"
28             android:gravity="center"/>
29 
30     </LinearLayout>
31 </layout>

2)寫一個通用的適配器Adaper,注意這裏和你以往寫的ListView的適配器徹底不同,咱們多了兩個屬性,一個是layoutId,一個是屬性id

 1 package com.example.nanchen.databindingdemo;
 2 
 3 import android.content.Context;
 4 import android.databinding.DataBindingUtil;
 5 import android.databinding.ViewDataBinding;
 6 import android.view.LayoutInflater;
 7 import android.view.View;
 8 import android.view.ViewGroup;
 9 import android.widget.BaseAdapter;
10 
11 import java.util.List;
12 
13 /**
14  * ListView的通用Adapter
15  * Created by 南塵 on 16-7-18.
16  */
17 public class CommonAdapter<T> extends BaseAdapter {
18     private Context context;//上下文環境
19     private List<T> list;//通用的,不知道數據
20     private int layoutId;//通用的,不知道佈局
21     private int variableId;//變量的id
22 
23     /**
24      * 構造方法
25      */
26     public CommonAdapter(Context context, List<T> list, int layoutId, int variableId) {
27         this.context = context;
28         this.list = list;
29         this.layoutId = layoutId;
30         this.variableId = variableId;
31     }
32 
33     @Override
34     public int getCount() {
35         if (list!=null)
36             return list.size();
37         return 0;
38     }
39 
40     @Override
41     public Object getItem(int position) {
42         return list.get(position);
43     }
44 
45     @Override
46     public long getItemId(int position) {
47         return position;
48     }
49 
50     @Override
51     public View getView(int position, View convertView, ViewGroup parent) {
52         ViewDataBinding binding = null;
53         if (convertView == null){
54             binding = DataBindingUtil.inflate(LayoutInflater.from(context),layoutId,parent,false);
55         }else{
56             binding = DataBindingUtil.getBinding(convertView);
57         }
58         binding.setVariable(variableId,list.get(position));
59         return binding.getRoot();
60     }
61 }

3)在xml中佈局,這個比較簡單,先在配置文件中把這個更改成程序入口,而且添加網絡操做權限,這裏用了BR文件,BR文件和R文件都是系統會自動生成的,只是R文件用於資源的id。圖片咱們就使用一個默認的

 1 package com.example.nanchen.databindingdemo;
 2 
 3 import android.databinding.DataBindingUtil;
 4 import android.os.Bundle;
 5 import android.support.v7.app.AppCompatActivity;
 6 
 7 import com.example.nanchen.databindingdemo.databinding.ActivityDataBindingListBinding;
 8 
 9 import java.util.ArrayList;
10 import java.util.List;
11 
12 public class DataBindingListActivity extends AppCompatActivity {
13 
14     @Override
15     protected void onCreate(Bundle savedInstanceState) {
16         super.onCreate(savedInstanceState);
17 //        setContentView(R.layout.activity_data_binding_list);
18         ActivityDataBindingListBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_data_binding_list);
19 
20         List<User> list = new ArrayList<>();
21         for (int i = 0; i < 100; i++) {
22             User user = new User();
23             user.setName("用戶 " + i );
24             user.setIcon("http://qlogo1.store.qq.com/qzone/503233512/503233512/100?1311741184");
25             list.add(user);
26         }
27         CommonAdapter<User> adapter = new CommonAdapter<>(
28                 this, list, R.layout.list_item, com.example.nanchen.databindingdemo.BR.user);
29         binding.setAdapter(adapter);
30 
31     }
32 
33 
34 }

 

4)大概能夠運行了哈。

 

5)如何添加點擊事件呢?別慌,在咱們的User中加入點擊方法就行了。

 1 package com.example.nanchen.databindingdemo;
 2 
 3 import android.view.View;
 4 import android.widget.Toast;
 5 
 6 /**
 7  * 繼承,觀察可刷新
 8  * Created by 南塵 on 16-7-18.
 9  */
10 public class User {
11     private String name;//用戶名
12     private String nickName;//暱稱
13     private String email;//郵箱
14 
15     private boolean vip;//是不是會員
16     private int level;//級別
17     private String icon;
18 
19     public String getIcon() {
20         return icon;
21     }
22 
23     public void setIcon(String icon) {
24         this.icon = icon;
25     }
26 
27     public int getLevel() {
28         return level;
29     }
30 
31     public void setLevel(int level) {
32         this.level = level;
33     }
34 
35     public boolean isVip() {
36         return vip;
37     }
38 
39     public void setVip(boolean vip) {
40         this.vip = vip;
41     }
42 
43     public User() {
44     }
45 
46     public User(String name, String nickName, String email) {
47         this.name = name;
48         this.nickName = nickName;
49         this.email = email;
50     }
51 
52     public String getEmail() {
53         return email;
54     }
55 
56     public void setEmail(String email) {
57         this.email = email;
58     }
59 
60     public String getName() {
61         return name;
62 
63     }
64 
65     public void setName(String name) {
66         this.name = name;
67     }
68 
69     public String getNickName() {
70         return nickName;
71     }
72 
73     public void setNickName(String nickName) {
74         this.nickName = nickName;
75     }
76 
77     public void clickName(View view){
78         Toast.makeText(view.getContext(),"點擊了用戶名:" + name,Toast.LENGTH_SHORT).show();
79     }
80 
81     public boolean longClickNickName(View view){
82         Toast.makeText(view.getContext(),"長按了暱稱:"+nickName,Toast.LENGTH_SHORT).show();
83         return true;
84     }
85 
86     public void click(View view){
87         setName(getName() + "( 已點擊 )");
88     }
89 }

6)這裏咱們點擊了用戶2,什麼狀況?沒刷新!!!!!,哦,哪裏出了問題!

 

7)調皮的滑動了一下滾動條,再回去發現才刷新更改了。

9)e duo key,這裏也太out了吧,說好的最屌框架呢?說好的要愉快一生呢?

仔細一看,才發現咱們的邏輯中出了一點小問題,這樣的話雖然你的list中的數據改變了,可是list並不知道,而這個adapter又沒有刷新數據的方法,怎麼辦?

這裏用到一個觀察者模式,只須要把User繼承BaseObservable類,而且在要更改的屬性上加一個@Bindble,再在setName方法中加入這樣一句話則可。

//刷新變量(變量id)
notifyPropertyChanged(com.example.nanchen.databindingdemo.BR.name);


 1 package com.example.nanchen.databindingdemo;
 2 
 3 import android.databinding.BaseObservable;
 4 import android.databinding.Bindable;
 5 import android.view.View;
 6 import android.widget.Toast;
 7 
 8 /**
 9  * 繼承,觀察可刷新
10  * Created by 南塵 on 16-7-18.
11  */
12 public class User extends BaseObservable {
13     private String name;//用戶名
14     private String nickName;//暱稱
15     private String email;//郵箱
16 
17     private boolean vip;//是不是會員
18     private int level;//級別
19     private String icon;
20 
21     public String getIcon() {
22         return icon;
23     }
24 
25     public void setIcon(String icon) {
26         this.icon = icon;
27     }
28 
29     public int getLevel() {
30         return level;
31     }
32 
33     public void setLevel(int level) {
34         this.level = level;
35     }
36 
37     public boolean isVip() {
38         return vip;
39     }
40 
41     public void setVip(boolean vip) {
42         this.vip = vip;
43     }
44 
45     public User() {
46     }
47 
48     public User(String name, String nickName, String email) {
49         this.name = name;
50         this.nickName = nickName;
51         this.email = email;
52     }
53 
54     public String getEmail() {
55         return email;
56     }
57 
58     public void setEmail(String email) {
59         this.email = email;
60     }
61 
62     @Bindable
63     public String getName() {
64         return name;
65 
66     }
67 
68     public void setName(String name) {
69         this.name = name;
70         //刷新變量(變量id)
71         notifyPropertyChanged(com.example.nanchen.databindingdemo.BR.name);
72     }
73 
74     public String getNickName() {
75         return nickName;
76     }
77 
78     public void setNickName(String nickName) {
79         this.nickName = nickName;
80     }
81 
82     public void clickName(View view){
83         Toast.makeText(view.getContext(),"點擊了用戶名:" + name,Toast.LENGTH_SHORT).show();
84     }
85 
86     public boolean longClickNickName(View view){
87         Toast.makeText(view.getContext(),"長按了暱稱:"+nickName,Toast.LENGTH_SHORT).show();
88         return true;
89     }
90 
91     public void click(View view){
92         setName(getName() + "( 已點擊 )");
93     }
94 }

10)再次運行:

 

如今好多了嘛,一點擊就刷新了,是否是很吊?額,如今是點擊整個item均可以刷新屬性界面,好吧,其實不管你點擊哪裏,只要你加上這個click方法做爲自定義屬性,均可以實現這個功能,這裏你要在原來的思路上實現是否是至關麻煩,而這個框架讓你只須要移動一行代碼的位置就能夠,很高端大氣上檔次有木有?

這裏作個示範,假如你是點擊頭像更改,只須要這樣。

 1 <?xml version="1.0" encoding="utf-8"?>
 2 
 3 <layout
 4     xmlns:android="http://schemas.android.com/apk/res/android"
 5     xmlns:app="http://schemas.android.com/apk/res-auto">
 6     
 7     <data>
 8         <variable
 9             name="user"
10             type="com.example.nanchen.databindingdemo.User"/>
11     </data>
12 
13     <LinearLayout
14         android:layout_width="match_parent"
15         android:layout_height="match_parent"
16         android:orientation="horizontal"
17         >
18         
19         <ImageView
20             android:layout_width="100dp"
21             android:layout_height="100dp"
22             app:imageUrl="@{user.icon}"
23             android:onClick="@{ user.click }"/>
24 
25         <TextView
26             android:layout_width="match_parent"
27             android:layout_height="match_parent"
28             android:text="@{user.name}"
29             android:gravity="center"/>
30 
31     </LinearLayout>
32 </layout>

 

不只能夠放在這裏,你還能夠放在任何地方,不管是在ListView裏面仍是外面。

確定這個框架還有其餘的東西的,你們一塊兒發掘咯~

相關文章
相關標籤/搜索