Flutter基礎類、錯誤態(tài)、加載態(tài)、無數(shù)據(jù)態(tài)等封裝

??Flutter中頁面沒有像Android、IOS 定義那么明確,Android中就是 Activity,IOS 中就是 UIViewController。

??在Flutter中,幾乎所有東西都是Widget。

將Widget視為可視組件(或與應用程序的可視方面交互的組件)。

??在項目開發(fā)中基本都會有一個 BaseActivity/BaseVIewController,封裝一些基本操作及公共部分,參照Android/IOS中 BaseActivity/BaseVIewController實現(xiàn),在 Flutter也實現(xiàn)同樣功能的 抽象的BaseWidget。

實現(xiàn)功能

  1. 開發(fā)頁面時,寫一個類繼承 BaseWidget,就會提示必須要實現(xiàn)的抽象方法,俗稱模板模式,要做的事情一目了然。這里將要寫的代碼定義成一個 Live Templates。
  2. 導航欄AppBar可以輕松隱藏和設置背景顏色(圖片),其中包含導航欄中的左邊返回鍵、中間的標題、右面的按鈕或文本,可以隨意設置隱藏和現(xiàn)實,當然可以重寫他們的方法,隨意設置自己的Widget,實現(xiàn)高度定制。
  3. 內置了一個錯誤頁面 ,主要用于網(wǎng)絡加載出錯或服務器返回錯誤的時候 ,可以直接調方法就顯示,不用每個頁面都寫錯誤頁面,避免需求變更時束手無策。
  4. 內置一個無數(shù)據(jù)頁面,用于列表無數(shù)據(jù)時展示。使用方法和功能和錯誤頁面差不多。
  5. 內置一個loading加載頁面,主要用于進入頁面時顯示一個 loading 視圖,默認進入界面就顯示,數(shù)據(jù)加載完成,顯示正常內容視圖,加載失敗話,就顯示上面定義的錯誤視圖。
  6. 進入自動調用 queryData 進行網(wǎng)絡請求。
  7. 內置了安全鍵盤,在要使用安全鍵盤頁面,初始化一下就可以了。
  8. 。。。
  9. 有了基類,以后拓展就很方面(如:返回刷新等)。

實現(xiàn)思路

??BaseWidget 是一個有狀態(tài)的基礎 Widget,由兩部分組成。

  • Widget 定義
abstract class BaseWidget extends StatefulWidget {
  @override
  BaseWidgetState createState() => getState();

  ///子類實現(xiàn)
  BaseWidgetState getState();
}

此部分在Widget的生命周期內不會發(fā)生變化,但可以接受可由其相應的State實例使用的參數(shù),當需要將其添加到窗口上時,可以通過實例化來實現(xiàn)。

  • Widget State 定義
abstract class BaseWidgetState<T extends BaseWidget> extends State<T> {
@override
void initState() {
  super.initState();
}


@override
Widget build(BuildContext context) {
  ...
  }

}

此部分是在Widget的生命周期中變化的部分,并強制每次應用修改時重建Widget的這個特定實例。
此兩部分別被子類繼承,并要求實現(xiàn)其抽象方法,getState 用于創(chuàng)建繼承BaseWidgetState的子類 Widget State實例。

布局搭建

在 BaseWidgetState 中內置了標題欄、錯誤視圖、空頁面視圖、加載中視圖、安全鍵盤等幾個基本控件,預留一個抽象方法buildWidget給子類搭建自己的布局。

@override
Widget build(BuildContext context) {
  return _hasSecurityKeyboard
      ? _buildWidgetWithKeyboard()
      : _buildWidgetDefault();
}

///構建默認視圖
Widget _buildWidgetDefault() {
  ///使用appbar,也可直接只有 body 在 body 里自定義狀態(tài)欄、標題欄
  return WillPopScope(
    child: Scaffold(
      appBar: _buildAppBar(),
      body: _buildBody(),
    ),
    onWillPop: _requestPop,
  );
}

///構建包含安全鍵盤視圖
Widget _buildWidgetWithKeyboard() {
  ///WidgetsApp或者MaterialApp,Flutter會自動默認創(chuàng)建一個Navigator
  ///用于鍵盤彈出的時候頁面可以滾動到輸入框的位置
  return WillPopScope(
    child: KeyboardMediaQuery(
      child: Builder(builder: (ctx) {
        ///初始化鍵盤監(jiān)聽并且傳遞當前頁面的context
        KeyboardManager.init(ctx);
        return Scaffold(
          appBar: _buildAppBar(),
          body: _buildBody(),
        );
      }),
    ),
    onWillPop: _requestPop,
  );
}

///物理返回
Future<bool> _requestPop() {
  bool b = true;
  if (KeyboardManager.isShowKeyboard) {
    KeyboardManager.hideKeyboard();
    b = false;
  }
  return Future.value(b);
}

///子類實現(xiàn),構建各自頁面UI控件 相當于setContentView()
Widget buildWidget(BuildContext context);

///構建內容區(qū)
Widget _buildBody() {
  return Container(
    ///內容區(qū)背景顏色
    color: LcfarmColor.colorF8F9F8,
    child: Stack(
      children: <Widget>[
        Offstage(
          offstage: !_isContentWidgetShow,
          child: buildWidget(context),
        ),
        _buildErrorWidget(),
        _buildEmptyWidget(),
        _buildLoadingWidget(),
      ],
    ),
  );
}

  • 通過 _hasSecurityKeyboard控制是否內置安全鍵盤,子類可以在 initState中通過初始化該字段來實現(xiàn)。
  • 同樣錯誤視圖、空白視圖、加載中視圖提供方法讓子類控制是否顯示,以及設置相應的文字、圖片等。

使用方法

  • 基本實現(xiàn)代碼如下:
class Test extends BaseWidget {
  @override
  BaseWidgetState getState() {
    return _TestState();
  }
}

class _TestState extends BaseWidgetState<Test> {
  @override
  Widget buildWidget(BuildContext context) {
    return Container();
  }
  
  @override
  void queryData() {
   
  }
}

  • getState 返回繼承BaseWidgetState的 Widget State。
  • buildWidget 用于構建當前視圖
  • queryData用于是否進入查詢數(shù)據(jù)

如有查詢,則直接調用網(wǎng)絡請求即可。

@override
void queryData() {
  _loadData(...)
}

如無需查詢數(shù)據(jù),則禁用掉即可。

@override
void queryData() {
  ///進入無需網(wǎng)絡請求數(shù)據(jù)
  disabledLoading();
}
  • 顯示成功視圖、錯誤視圖、空白視圖
void _loadData(LoadType type) {
  AccountService.letterList(
    pageNo,
    (Pager<LetterModel> pager) {
      ///暫無數(shù)據(jù)
      if (pager.total == 0) {
        showLoadEmpty();
        return;
      }
      pageNo = pager.currentPage;
      if (type == LoadType.loadMore) {
        letterModels.addAll(pager.list);
      } else {
        letterModels = pager.list;
      }

      showLoadSuccess();
    },
    (HttpError error) {
      showLoadFailure(error.code, error.message);
    },
  );
}

最后

??如果在使用過程遇到問題,歡迎下方留言交流。

學習資料

請大家不吝點贊!因為您的點贊是對我最大的鼓勵,謝謝!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Flutter是谷歌的移動UI框架,可以快速在iOS和Android上構建高質量的原生用戶界面。 Flutter可...
    Cat9527閱讀 779評論 0 1
  • 昨天下午,我們一家三口相約出去吃海鮮大餐。我和媽媽到了酒店,但是爸爸沒到,我們等啊等終于爸爸出現(xiàn)了,可是己經(jīng)過了一...
    西安臭蛋的爸爸閱讀 360評論 1 0
  • 今天早上六點半起來就回來上班了,我走時媽媽又睡覺了,后來打電話給哥哥,哥哥說我走了,他就去了,媽媽醒了,喝了一碗奶...
    心境如花閱讀 158評論 0 0
  • 說起情詩來,你想到的可能是《上邪》里“上邪!我欲與君相知,長命無絕衰。山無陵,江水為竭,冬雷震震,夏雨雪,天地合,...
    醉懂閱讀 363評論 0 1
  • 曾經(jīng)在網(wǎng)上看到一段話:父母是我們和死神之間的一道屏障,父母在,人生尚有來處;父母去,人生只剩歸途。...
    人生有味是清歡丶閱讀 132評論 0 1

友情鏈接更多精彩內容