1. 程式人生 > >Android Databinding 從入門到轉行(三)在xml檢視將ViewModel成員注入到View的setXXX方法

Android Databinding 從入門到轉行(三)在xml檢視將ViewModel成員注入到View的setXXX方法

注入規則:

條件:某View中如含方法:setXXX,    引數唯一,型別為T

        注入步驟:在ViewModel中,新增 T  型別成員引用t

       注入方法:在對應的xml,的根元素layout, 新增

xmlns:app="http://schemas.android.com/apk/res-auto

      然後,找到某View , 新增app:xxxx="@{model.t}" ,就可以完成注入。


關說不幹,不懂啥意思,讓我們來實戰。

需求三:

UI效果圖:

  

第一步:實現UI

<?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="userModel"
            type="com.yoyonewbie.mvvm.vm.UserModel" />
    </data>

    <android.support.v4.widget.SwipeRefreshLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        
        >

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                android:padding="16dp">


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

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="姓名:" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@{userModel.name}" />
                </LinearLayout>


                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/activity_vertical_margin"
                    android:orientation="horizontal">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="年齡:" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@{userModel.age}" />
                </LinearLayout>


            </LinearLayout>
        </ScrollView>
    </android.support.v4.widget.SwipeRefreshLayout>
</layout>

那麼在databinding中下拉事件回撥是怎麼實現的呢?

按正常來實現,就是在MainActivity裡面,通過findViewById加載出例項,再設定事件回撥.如下

swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
    @Override
public void onRefresh() {
        
    }
});

那麼,我們觀察setOnRefreshListener這個方法,setXXX(唯一引數),那麼滿足viewmodel的成員可 在view的xml編寫注入變數的需求。

那麼我們就可以填空:

條件:SwipeRefreshLayout含方法:setOnRefreshListener,    引數唯一,型別為SwipeRefreshLayout.OnRefreshListener

        注入步驟:在UserModel 中,新增 SwipeRefreshLayout.OnRefreshListener 型別成員引用onRefreshListener 

       注入方法:在對應的xml,的根元素layout, 新增

xmlns:app="http://schemas.android.com/apk/res-auto

      然後,找到SwipeRefreshLayout

, 新增app:onRefreshListener="@{userModel.onRefreshListener}" ,就可以完成注入。


實現程式碼:

package com.yoyonewbie.mvvm.vm;



import android.databinding.Observable;
import android.databinding.ObservableBoolean;
import android.databinding.ObservableField;
import android.databinding.ObservableInt;
import android.support.v4.widget.SwipeRefreshLayout;
import android.view.View;

public class UserModel {


    public ObservableField<String> name=  new ObservableField<String>();

    public   ObservableField<String>  age=new ObservableField<String>();

    public void init()
    {
        name.set("未載入") ;
        age.set("未載入");
    }


    /**
     * 是重新整理使用者資料
     */
    public void freshUserInfo()
    {
        name.set("Sam") ;
        age.set("25");
    }

    public SwipeRefreshLayout.OnRefreshListener onRefreshListener = new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            freshUserInfo();
        }
    };



}


<?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="userModel"
            type="com.yoyonewbie.mvvm.vm.UserModel" />
    </data>

    <android.support.v4.widget.SwipeRefreshLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:onRefreshListener="@{userModel.onRefreshListener}"
        >

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                android:padding="16dp">


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

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="姓名:" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@{userModel.name}" />
                </LinearLayout>


                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/activity_vertical_margin"
                    android:orientation="horizontal">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="年齡:" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@{userModel.age}" />
                </LinearLayout>


            </LinearLayout>
        </ScrollView>
    </android.support.v4.widget.SwipeRefreshLayout>
</layout>


package com.yoyonewbie.mvvm.view.activity;

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

import com.yoyonewbie.mvvm.vm.UserModel;
import com.yoyonewbie.test.R;
import com.yoyonewbie.test.databinding.MainActivityBinding;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        MainActivityBinding mainActivityBinding = DataBindingUtil.setContentView(this, R.layout.main_activity);
        UserModel user = new UserModel();
        user.init();
        mainActivityBinding.setUserModel(user);
    }



}



效果:


下拉後:


這時候,我想改變下拉狀態怎麼辦 ?

改變下拉狀態,需要呼叫setRefreshing(boolean)方法。

觀察下,這個方法也滿足注入的條件是不是?走一下思路!!!!

條件:SwipeRefreshLayout含方法:setRefreshing,    引數唯一,型別為boolean

        注入步驟:在UserModel 中,新增  ObserverBoolean(因為操作超過2次不用boolean)型別成員引用isRefreshing

       注入方法:在對應的xml,的根元素layout, 新增

xmlns:app="http://schemas.android.com/apk/res-auto

      然後,找到SwipeRefreshLayout , 新增app:refreshing="@{userModel.isRefreshing}" ,就可以完成注入。

補全程式碼:

package com.yoyonewbie.mvvm.vm;



import android.databinding.Observable;
import android.databinding.ObservableBoolean;
import android.databinding.ObservableField;
import android.databinding.ObservableInt;
import android.os.Handler;
import android.support.v4.widget.SwipeRefreshLayout;
import android.view.View;

public class UserModel {


    public ObservableField<String> name=  new ObservableField<String>();

    public   ObservableField<String>  age=new ObservableField<String>();

    public  ObservableBoolean isRefreshing = new ObservableBoolean();




    public void init()
    {
        name.set("未載入") ;
        age.set("未載入");
    }


    /**
     * 是重新整理使用者資料
     */
    public void freshUserInfo()
    {
        name.set("Sam") ;
        age.set("25");
    }

    public SwipeRefreshLayout.OnRefreshListener onRefreshListener = new SwipeRefreshLayout.OnRefreshListener() {
        @Override
        public void onRefresh() {
            isRefreshing.set(true);
            freshUserInfo();
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    isRefreshing.set(false);
                }
            }, 1000);
        }
    };



}


<?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="userModel"
            type="com.yoyonewbie.mvvm.vm.UserModel" />
    </data>

    <android.support.v4.widget.SwipeRefreshLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:onRefreshListener="@{userModel.onRefreshListener}"
        app:refreshing ="@{userModel.isRefreshing}"
        >

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                android:padding="16dp">


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

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="姓名:" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@{userModel.name}" />
                </LinearLayout>


                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="@dimen/activity_vertical_margin"
                    android:orientation="horizontal">

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="年齡:" />

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="@{userModel.age}" />
                </LinearLayout>


            </LinearLayout>
        </ScrollView>
    </android.support.v4.widget.SwipeRefreshLayout>
</layout>