欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

Android頁面多狀態(tài)布局管理的開發(fā)

一、現(xiàn)狀

創(chuàng)新互聯(lián)自2013年創(chuàng)立以來,先為孝昌等服務(wù)建站,孝昌等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為孝昌企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

頁面多狀態(tài)布局是開發(fā)中常見的需求,即頁面在不同狀態(tài)需要顯示不同的布局,實(shí)現(xiàn)的方式也比較多,最簡單粗暴的方式就是在 XML 中先將不同狀態(tài)對應(yīng)的布局隱藏起來,根據(jù)需要改變其可見狀態(tài),如果多個界面公用相同的狀態(tài)布局,缺點(diǎn)也很明顯,繁瑣、重復(fù)、不優(yōu)雅等,類似的實(shí)現(xiàn)也可以使用 ViewStub,這樣性能會更好些。所以我們要做的就是盡可能避免這些方式所導(dǎo)致的問題,更加高效、優(yōu)雅的管理不同的狀態(tài)布局。

二、目標(biāo)

我們要實(shí)現(xiàn)的 StatusView要實(shí)現(xiàn)的主要功能如下:

  • 可在 Activity、Fragment 、XML 中使用,可作用于XML的根布局View或其子View
  • 支持默認(rèn)的狀態(tài)布局,可進(jìn)行常規(guī)配置
  • 可自定義狀態(tài)布局
  • 狀態(tài)布局懶加載,僅在初次顯示時初始化

效果預(yù)覽如下:

Android 頁面多狀態(tài)布局管理的開發(fā)

preview

三、實(shí)現(xiàn)

這里只對實(shí)現(xiàn)過程中一些比較重要的點(diǎn)進(jìn)行分析。

3.1、初始化

首先有一個最重要的知識點(diǎn)需要明確,XML 布局中的每個View都有其對應(yīng)的父 View,必然在其父View中都有固定的位置,如果是 Activity 對應(yīng)的 XML,那XML根布局View的父View是誰呢?其實(shí)就是一個 id 為 android.R.id.content 的 View,如果是 Fragment 對應(yīng)的 XML,那 XML 根布局 View 的父 View 可以通過 fragment.getView() 方法得到。所以現(xiàn)在我們可以得到XML 中每一個View和對應(yīng)的 LayoutParams 位置信息。

既然有了 View 和其對應(yīng)的 LayoutParams 位置信息,就可以通過其父 View 將指定的子 View 移除掉,然后將 StatusView 添加到被移除的 View 的位置,進(jìn)而就可以控制 StatusView 來切換不同的狀態(tài)布局。

簡單總結(jié)下,就是用 StatusView 替換掉要進(jìn)行多狀態(tài)布局切換的 View,這個 View 可以時 XML 中的任意 View。這也是直接在 Activity、Fragment 中使用 StatusView 要做的核心初始化工作。

那么 StatusView 又是個什么呢?其實(shí)就是一個繼承了 FrameLayout 的 ViewGroup,之所以要繼承 FrameLayout,因?yàn)?StatusView 此時僅僅是作為父容器存在的,并不關(guān)心內(nèi)部各種狀態(tài) View 的具體情況,所以使用 FrameLayout 就夠了,更有通用性。這樣 StatusView 也就可以在 XML 中使用了

先將上邊這部分內(nèi)容轉(zhuǎn)化成代碼:

public class StatusView extends FrameLayout {
  ......
  /**
   * 在 Activity 中的初始化方法,默認(rèn)頁面的根布局使用多狀態(tài)布局
   */
  public static StatusView init(Activity activity) {
    View contentView = ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
    return init(contentView);
  }

  /**
   * 在 Activity 中的初始化方法
   * @param viewId  使用多狀態(tài)布局的 ViewId
   */
  public static StatusView init(Activity activity, @IdRes int viewId) {
    View rootView = ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
    View contentView = rootView.findViewById(viewId);
    return init(contentView);
  }

  /**
   * 在Fragment中的初始化方法
   * @param viewId  使用多狀態(tài)布局的 ViewId
   */
  public static StatusView init(Fragment fragment, @IdRes int viewId) {
    View rootView = fragment.getView();
    View contentView = null;
    if (rootView != null) {
      contentView = rootView.findViewById(viewId);
    }
    return init(contentView);
  }

  /**
   * 用 StatusView 替換要使用多狀態(tài)布局的 View
   */
  private static StatusView init(View contentView) {
    if (contentView == null) {
      throw new RuntimeException("ContentView can not be null!");
    }
    ViewGroup parent = (ViewGroup) contentView.getParent();
    if (parent == null) {
      throw new RuntimeException("ContentView must have a parent view!");
    }
    ViewGroup.LayoutParams lp = contentView.getLayoutParams();
    int index = parent.indexOfChild(contentView);
    parent.removeView(contentView);
    StatusView statusView = new StatusView(contentView.getContext());
    statusView.addView(contentView);
    statusView.setContentView(contentView);
    parent.addView(statusView, index, lp);
    return statusView;
  }
  ......
}

如果在 XML 中使用 StatusView 如何進(jìn)行初始化呢,自然是通過 onFinishInflate() 方法:

@Override
protected void onFinishInflate() {
  super.onFinishInflate();
  if (getChildCount() == 1) {
    View view = getChildAt(0);
    setContentView(view);
  }
}

3.2、狀態(tài)布局的切換

StatusView 默認(rèn)支持 Loading、Empty、Error 三種狀態(tài)布局,加上原始的頁面內(nèi)容布局,一共四種。切換狀態(tài)布局時,我們做法是直接從 StatusView 中移除掉正在顯示的狀態(tài)布局,然后添加要顯示的狀態(tài)布局:

private void switchStatusView(View statusView) {
  if (statusView == currentView) {
    return;
  }
  removeView(currentView);
  currentView = statusView;
  addView(currentView);
}

3.3、狀態(tài)布局的懶加載

在APP使用環(huán)境良好的情況下,有些狀態(tài)布局可能根本沒有顯示的機(jī)會,如果在初始化時一股腦的加載出來自然不可取,影響性能,所以我們要做的就是按需加載,即僅在狀態(tài)布局初次顯示時加載并初始化,之后復(fù)用即可:

private View generateStatusView(@LayoutRes int layoutId) {
    View statusView = viewArray.get(layoutId);
    if (statusView == null) {
      statusView = inflate(layoutId);
      viewArray.put(layoutId, statusView);
      configStatusView(layoutId, statusView);
    }
    return statusView;
  }

3.4、更自由的用法

一般的多狀態(tài)布局管理都會提供默認(rèn)的 Loading、Empty、Error 三種狀態(tài)布局,并可以自定義對應(yīng)的狀態(tài)布局, 并提供對應(yīng)的開放 api。但這樣會有些局限性,如果有其它業(yè)務(wù)場景的狀態(tài)布局,雖然布局文件可以自定義,但原有的api方法調(diào)用起來難免會有違和感,并不友好!所以有必要在常用業(yè)務(wù)場景的基礎(chǔ)上再提供更加通用的api方法,并不局限于特定的場景。

目前的做法是用狀態(tài)布局和對應(yīng)的索引之間的關(guān)系來實(shí)現(xiàn):

// 添加指定索引對應(yīng)的狀態(tài)布局
statusView.setStatusView(int index, @LayoutRes int layoutId)
// 為指定索引的狀態(tài)布局設(shè)置初次顯示的監(jiān)聽事件,用來進(jìn)行狀態(tài)布局的相關(guān)初始化
statusView.setOnStatusViewConvertListener(int index, StatusViewConvertListener listener)
// 顯示指定索引的狀態(tài)布局
statusView.showStatusView(int index)

3.5、注意事項(xiàng)

  • 當(dāng) Fragment 布局文件的根 View 使用 StatusView 時,為避免出現(xiàn)的異常問題,建議在 XML 中初始化!
  • 當(dāng)直接在 Fragment 中使用時,init()方法需要在onCreateView()之后的生命周期方法中執(zhí)行!
  • 由于StatusView 繼承自 FrameLayout,所以會多一層布局嵌套。

主要的點(diǎn)就這么多了,剩下的就是些屬性配置的內(nèi)容,其實(shí)挺簡單的,更多細(xì)節(jié)和用法可參考GitHub: StatusView

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。

網(wǎng)頁標(biāo)題:Android頁面多狀態(tài)布局管理的開發(fā)
文章路徑:http://aaarwkj.com/article4/jegjie.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營銷型網(wǎng)站建設(shè)、、手機(jī)網(wǎng)站建設(shè)、搜索引擎優(yōu)化、網(wǎng)站營銷服務(wù)器托管

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司
黄片在线免费在线播放| 国产精品v一区二区三区| 亚洲精品成人在线国产| 99精品人妻一区二区三区| 韩国三级伦理中文字幕| 国产日韩视频一区二区| 男人av天堂手机在线| 国产成人av麻豆色哟哟| 久久国产精品成人免费蜜臀| 一区二区三区深夜福利| 综合激情网激情五月天| 日本中文字幕在线播放一区| 97色伦综合在线欧美视频| 亚洲综合色一区二区三区四区| 久久精品一区二区三区乱码| 亚洲熟妇av一区二区三区| 中文国产人精品久久蜜桃| 粉嫩一区二区三区精品视频| 99久久精品人妻少妇一| 开心五月六月婷婷在线| 成年人性生活一级视品| 亚洲精品一区二区影院| 亚洲久久精品中文字幕| 亚洲乱码中文字幕在线观看| 久久久久精品激情三级| 蜜桃视频在线观看91| 最新91熟女九色地址| 日本欧美中文字幕一区| 老熟女露脸吞精一二三四区| 国产高清不卡一二三区| 黄色免费大片在线播放| 亚洲黄片在线免费播放观看| 日韩精品一区二区国产| 日韩有码在线中文字幕| 日本欧美三级一二三区| 一区二区三区毛片免费| 日本一区二区电影大全| 日本色网一区二区三区四区| 国产熟女一区二区精品视频| 国内精品久久久久久2021| 日本精品一区二区三区免费|