国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

android使用DataBinding來設置空狀態

2019-12-12 03:22:37
字體:
來源:轉載
供稿:網友

寫在前面

在平時的開發之中,我們需要對于數據加載的情況進行展示:

  1. 空數據
  2. 網絡異常
  3. 加載中等等情況

現在設置頁面狀態的方式有多種,由于筆者近期一直在使用databinding,而數據綁定通過改變模型來展示view的方式和狀態頁的設置也滿契合的。

所以這里就講講使用databinding來設置android中的各種狀態頁。很簡單,先看看效果


首先

在app的build.gradle文件中開啟databinding

android{  ...  dataBinding {    enabled = true  }}

我們先定義一些用于狀態的注解EmptyState

/** * 頁面描述:空狀態 * <p> * Created by ditclear on 2017/2/24. */@IntDef({NORMAL, PROGRESS, EMPTY, NET_ERROR, NOT_AVAILABLE})@Retention(RetentionPolicy.SOURCE)public @interface EmptyState {  int NORMAL = -1; //正常  int PROGRESS = -2;//顯示進度條  int EMPTY = 11111; //列表數據為空  int NET_ERROR = 22222; //網絡未連接  int NOT_AVAILABLE = 33333; //服務器不可用  //...各種頁面的空狀態,可以自己定義、添加}

再自定義一個異常EmptyException用于顯示我們需要的狀態信息

/** * 頁面描述:異常 * <p> * Created by ditclear on 2017/3/5. */public class EmptyException extends Exception {  private int code;  public EmptyException(@EmptyState int code) {    super();    this.code = code;  }  @EmptyState  public int getCode() {    return code;  }  public void setCode(@EmptyState int code) {    this.code = code;  }}

現在,大多數展示狀態頁的控件都會提供

  1. 加載中的進度條
  2. 錯誤信息
  3. 空狀態
  4. ...

所以我們的目標也是顯示這些

布局

以數據綁定的形式進行布局,使用StateModel來控制狀態頁展示的消息

<?xml version="1.0" encoding="utf-8"?><layout xmlns:android="http://schemas.android.com/apk/res/android"  >  <data>    <import type="android.view.View"/>    <variable      name="stateModel"      type="com.ditclear.app.state.StateModel"/>  </data>  <RelativeLayout    android:id="@+id/rv_empty_view"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@color/background"    android:clickable="true"    android:focusableInTouchMode="true"    android:visibility="@{stateModel.empty?View.VISIBLE:View.GONE}">    <android.support.v4.widget.ContentLoadingProgressBar      style="?android:attr/progressBarStyle"      android:layout_width="wrap_content"      android:layout_height="wrap_content"      android:layout_centerInParent="true"      android:visibility="@{stateModel.progress?View.VISIBLE:View.GONE}"/>    <LinearLayout      android:layout_width="match_parent"      android:layout_height="match_parent"      android:layout_alignParentBottom="true"      android:layout_alignParentLeft="true"      android:layout_alignParentStart="true"      android:gravity="center"      android:orientation="vertical"      android:visibility="@{stateModel.progress?View.INVISIBLE:View.VISIBLE}">      <ImageView        android:id="@+id/none_data"        android:layout_width="345dp"        android:layout_height="180dp"        android:scaleType="fitCenter"        android:src="@{stateModel.emptyIconRes}"/>      <TextView        android:layout_width="wrap_content"        android:layout_height="25dp"        android:layout_below="@+id/none_data"        android:layout_centerHorizontal="true"        android:text="@{stateModel.currentStateLabel}"        android:textSize="16sp"/>    </LinearLayout>  </RelativeLayout></layout>

布局文件中有幾個方法

  1. empty 用于控制狀態頁是顯示還是隱藏,數據加載正常(即狀態為NORMAL)的時候隱藏,否則展示
  2. isProgress 是否顯示加載中,如果顯示進度條(即狀態為PROGRESS),就隱藏異常頁
  3. emptyIconRes 顯示狀態的圖片信息
  4. currentStateLabel 顯示狀態的文字消息

我們定義狀態的ViewModel ,就叫StateModel,來控制狀態

/** * 頁面描述:狀態頁面設置模型 * <p> * Created by ditclear on 2017/2/24. */public class StateModel extends BaseObservable {  private Context mContext = MyApp.instance();  @EmptyState  private int emptyState = EmptyState.NORMAL;  private boolean empty;  public int getEmptyState() {    return emptyState;  }  /**   * 設置狀態   *   * @param emptyState   */  public void setEmptyState(@EmptyState int emptyState) {    this.emptyState = emptyState;    notifyChange();  }  /**   * 顯示進度條   *   * @return   */  public boolean isProgress() {    return this.emptyState == EmptyState.PROGRESS;  }  /**   * 根據異常顯示狀態   *   * @param e   */  public void bindThrowable(Throwable e) {    if (e instanceof EmptyException) {      @EmptyState      int code = ((EmptyException) e).getCode();      setEmptyState(code);    }  }  public boolean isEmpty() {    return this.emptyState != EmptyState.NORMAL;  }  /**   * 空狀態信息   *   * @return   */  @Bindable  public String getCurrentStateLabel() {    switch (emptyState) {      case EmptyState.EMPTY:        return mContext.getString(R.string.no_data);      case EmptyState.NET_ERROR:        return mContext.getString(R.string.please_check_net_state);      case EmptyState.NOT_AVAILABLE:        return mContext.getString(R.string.server_not_avaliabe);      default:        return mContext.getString(R.string.no_data);    }  }  /**   * 空狀態圖片   *   * @return   */  @Bindable  public Drawable getEmptyIconRes() {    switch (emptyState) {      case EmptyState.EMPTY:        return ContextCompat.getDrawable(mContext, R.drawable.ic_visibility_off_green_400_48dp);      case EmptyState.NET_ERROR:        return ContextCompat.getDrawable(mContext, R.drawable.ic_signal_wifi_off_green_400_48dp);      case EmptyState.NOT_AVAILABLE:        return ContextCompat.getDrawable(mContext, R.drawable.ic_cloud_off_green_400_48dp);      default:        return ContextCompat.getDrawable(mContext, R.drawable.ic_visibility_off_green_400_48dp);    }  }}

很普通的視圖模型,主要有幾個用于判斷狀態顯示的方法

  1. bindThrowable 根據異常顯示狀態
  2. setEmptyState 方法用來設置當前的狀態,通過notifyChange來通知布局文件改變

下面講講實際運用:

在activity或者fragment布局中,添加狀態頁的布局

<?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>    <import type="android.view.View"/>    <variable      name="stateModel"      type="com.ditclear.app.state.StateModel"/>  </data>  <com.ditclear.app.ScrollChildSwipeRefreshLayout    android:id="@+id/refresh_layout"    android:layout_width="match_parent"    android:layout_height="match_parent">    <RelativeLayout      android:id="@+id/container"      android:layout_width="match_parent"      android:layout_height="match_parent"      android:orientation="vertical">      <android.support.v4.widget.NestedScrollView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:fillViewport="false"        android:overScrollMode="always"        android:visibility="@{stateModel.empty?View.GONE:View.VISIBLE}">        <TextView          android:id="@+id/content_tv"          android:layout_width="match_parent"          android:layout_height="match_parent"          android:gravity="center"/>      </android.support.v4.widget.NestedScrollView>      <include        layout="@layout/widget_layout_empty"        app:stateModel="@{stateModel}"/>    </RelativeLayout>  </com.ditclear.app.ScrollChildSwipeRefreshLayout></layout>

最后在activity或者fragment中我們只需要通過state.bindThrowable()和state.setEmptyState()方法便可以輕松設置各種各樣的狀態。

loadData().subscribe(new Subscriber<List<Contributor>>() {  @Override  public void onStart() {    super.onStart();    if (!mMainBinding.refreshLayout.isRefreshing()) {      mStateModel.setEmptyState(EmptyState.PROGRESS);    }  }  @Override  public void onCompleted() {    mStateModel.setEmptyState(EmptyState.NORMAL);  }  @Override  public void onError(Throwable e) {    mMainBinding.refreshLayout.setRefreshing(false);    mStateModel.bindThrowable(e);    Toast.makeText(MainActivity.this, mStateModel.getCurrentStateLabel(), Toast.LENGTH_SHORT).show();  }  @Override  public void onNext(List<Contributor> contributors) {    mMainBinding.refreshLayout.setRefreshing(false);    if (contributors == null || contributors.isEmpty()) {      onError(new EmptyException(EmptyState.EMPTY));    } else {      mMainBinding.contentTv.setText(contributors.toString());    }  }});

寫在最后

對于要使用數據來控制視圖狀態的,使用databinding實在是一個事半功倍的方式。而且也十分容易理解。

最后demo地址:StateBinding_jb51.rar

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 堆龙德庆县| 襄城县| 乌苏市| 桃园市| 浦东新区| 南京市| 邹城市| 临沧市| 辽宁省| 辽中县| 读书| 六枝特区| 呼图壁县| 池州市| 阿图什市| 图们市| 九龙县| 上杭县| 营山县| 晋江市| 醴陵市| 南充市| 普安县| 长葛市| 清涧县| 永顺县| 宁蒗| 昭觉县| 那曲县| 浏阳市| 淮安市| 韶关市| 富川| 根河市| 长海县| 阿拉尔市| 宣武区| 新河县| 安徽省| 虹口区| 嵩明县|