Android databinding xml中處理數據與控件綁定

studio對mvvm支持的也在不停的更新,但是還是有些問題沒有解決,比如說:

xml中加載圖片編譯時會爆出警告,xml中設置數據有幾種情況沒有提示,編譯時xml中出現錯誤並不會定位到錯誤的位置,等一些問題。

我相信這些問題很快會解決,現如今看mvvm還是很不錯的。

我接觸和開始使用mvvm是半年多前,當時真的只是爲了省略findViewById(哈哈),經過這幾個月的項目,慢慢才認識到mvvm的好處。

也踩了不少的坑,下面就記錄一下mvvm在xml中綁定數據的幾種處理方式。

首先我新建了一個工程在build.gradle中加入:

dataBinding{
        enabled = true
    }
然後將mainactivity的xml佈局修改一下,即在原來最外層的viewgroup外面在套一層<layout></layout>標籤,現在佈局是這個樣子的:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.xian.ge.myapplication.MainActivity">

        

    </LinearLayout>

</layout>

這樣回到activity中,修改原來的setContentView,變成下面這樣:

public class MainActivity extends AppCompatActivity {

    private ActivityMainBinding activityMainBinding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);

    }
}

解釋幾句:

上面代碼中ActivityMainBinding這個對象是系統幫我們生成的。

例子:如果你的xml名字叫activity_first.xml的話,在你xml包上layout標籤的時候就會生成名字叫ActivityFirstBinding的對象。

如果你在activity中找不到的話,那就試着rebuild一下,重新編譯一次後就會找到。

下面最後一項準備工作,建一個實體類,這裏我就寫個簡單的用戶表,包括了名字,年齡,還有一個布爾的值用來控制是否顯示:

/**
 * 用戶信息表
 * Created by ge on 2017/5/7.
 */

public class UserEntity {
    
    private String userName;
    private int userAge;
    private boolean isShow;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public int getUserAge() {
        return userAge;
    }

    public void setUserAge(int userAge) {
        this.userAge = userAge;
    }

    public boolean isShow() {
        return isShow;
    }

    public void setShow(boolean show) {
        isShow = show;
    }
}

哦還有一個,我在xml中寫幾個view,方便下面演示:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.xian.ge.myapplication.MainActivity">

        <TextView
            android:id="@+id/tv_user_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/tv_user_age"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <ImageView
            android:id="@+id/iv_user_head"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <Button
            android:id="@+id/btn_show"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="年齡段"/>

    </LinearLayout>

</layout>

好了準備工作做完了。大家可以看到上面幾個控件我都起好了id。

下面就直接演示mvvm最基本的功能。。。省去了findViewById。

在activity中不用像以前一樣先去找到view在進行設置直接用剛纔實例化的binding對象就能找到:

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);


        activityMainBinding.tvUserName.setText("葛大寶");
        activityMainBinding.tvUserAge.setText("24歲");
        activityMainBinding.btnShow.setText("青少年");


    }

是不是很簡單。

實際項目中的數據一般都是我們請求拿到之後然後再設置,下面就看看在activity中設置數據變成了什麼樣子:

1.首先在xml中加入<data>標籤:


<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <variable
            name="userInfo"
            type="com.xian.ge.myapplication.UserEntity"/>

    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.xian.ge.myapplication.MainActivity">

        <!-- 節省地方省略其中控件,文章上面有 -->

    </LinearLayout>

</layout>

這樣就直接在activity中設置數據了,如下:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);


        // 模擬拿到數據
        UserEntity userEntity = new UserEntity();
        userEntity.setUserName("葛大寶1");
        userEntity.setShow(false);
        userEntity.setUserAge(24);

        // 設置到xml中顯示
        activityMainBinding.setUserInfo(userEntity);

    }

設置了之後我們就要回到xml中進入今天正題:

1.首先顯示名字:

<TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{userInfo.userName}"/>

這是最簡單的直接@符號加{},中間用上面引入的數據對象設置即可。

2.控制button的顯示或隱藏:

因爲涉及到View的使用,所以要在data中引入View:

 <data>

        <import type="android.view.View"/>
        
        <variable
            name="userInfo"
            type="com.xian.ge.myapplication.UserEntity"/>

    </data>

這時候就可以直接使用了:

 <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="年齡段"
            android:visibility="@{userInfo.show ? View.GONE : View.VISIBLE}"/>

大家看到這是用布爾類型來判斷,但是實際項目中不可能全是這麼簡單的判斷條件,可能需要通過一個int類型或者string類型來判斷,

那麼這時候就涉及到了引入外部工具類來幫助我們處理這個數據。

加入現在我們的判斷規則是,根據年齡來控制按鈕的顯隱性,年齡大於五十歲的隱藏,小於五十歲的顯示,

那麼首先我新建一個工具類:

/**
 * 工具類
 * Created by ge on 2017/5/7.
 */

public class DataUtils {
    
    public static boolean isShow(int age){
        return age < 50;
    }
}

在xml中引入工具類:

<data>

        <import type="android.view.View"/>
        <import type="com.xian.ge.myapplication.DataUtils" alias="dataUtils"/>
        
        <variable
            name="userInfo"
            type="com.xian.ge.myapplication.UserEntity"/>

    </data>

大家看到我給工具類設置了一個別名,下面view中使用別名即可:

 <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="年齡段"
            android:visibility="@{dataUtils.isShow(userInfo.userAge) ? View.GONE : View.VISIBLE}"/>

3.基礎類型引用

換一個場景,現在我的一個textView要顯示年齡,但是年齡是int類型,這時候根在class中沒啥區別:

<TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{String.valueOf(userIfo.userAge)}"/>

像string,int, float等是不需要像上面使用View一樣在data中import進來的。


4.圖片的設置

新建圖片加載工具類:

/**
 * 圖片加載
 * Created by ge on 2017/5/5.
 */

public class ImageLoadViewModel {
    
    @BindingAdapter({"bind:testState"})
    public static void loadChildStateImg(ImageView view, String path){
        Glide.with(view.getContext()).load(path)
                .placeholder(path)
                .into(view);
    }

}

在xml中使用:

 <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:testState="@{"圖片路徑"}"/>

參數傳的string,是圖片的路徑。

實際項目中也可能給你的不是個路徑,而是根據類型加載不同的圖片,也可能是本地圖片,那麼下面看下。

加載圖片的工具方法換成:

 @BindingAdapter({"bind:testState"})
    public static void loadChildStateImg(ImageView view, int type){
        
        if (type == 1){
            Glide.with(view.getContext()).load(path)
                    .placeholder(path)
                    .into(view);
        }else {
            Glide.with(view.getContext()).load(path)
                    .placeholder(path)
                    .into(view);
        }
    }
加載圖片按照上述寫法,編譯的時候會爆一個警告,不要理他。



先記錄到這,只寫了一些基本的用法,mvvm還有很多牛逼的地方,慢慢來。

如果你項目已經寫好了,想試試也沒關係,從最簡單的findViewById開始。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章