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
實現程式碼:
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>