Flutter四種頁面視圖,加載中,無數(shù)據(jù),加載失敗,成功視圖

我們常常會遇到以下的場景:
頁面已打開,首先需要請求網(wǎng)絡,此時頁面展示加載中的視圖;
網(wǎng)絡請求完畢之后,會出現(xiàn)以下幾種情況:

  • 遇到各種問題,出現(xiàn)加載失敗的情況,但是又可以重新加載
  • 加載完后無數(shù)據(jù),需要展示無數(shù)據(jù)的屬兔
  • 加載成功,展示需要展示的頁面

根據(jù)以上場景,我封裝了一個自定義組件來滿足以上要求

///四種視圖狀態(tài)
enum LoadState { State_Success, State_Error, State_Loading, State_Empty }

///根據(jù)不同狀態(tài)來展示不同的視圖
class LoadStateLayout extends StatefulWidget {

  final LoadState state; //頁面狀態(tài)
  final Widget successWidget;//成功視圖
  final VoidCallback errorRetry; //錯誤事件處理

  LoadStateLayout(
      {Key key,
      this.state = LoadState.State_Loading,//默認為加載狀態(tài)
      this.successWidget,
      this.errorRetry})
      : super(key: key);

  @override
  _LoadStateLayoutState createState() => _LoadStateLayoutState();
}

class _LoadStateLayoutState extends State<LoadStateLayout> {
  @override
  Widget build(BuildContext context) {
    return Container(
      //寬高都充滿屏幕剩余空間
      width: double.infinity,
      height: double.infinity,
      child: _buildWidget,
    );
  }

  ///根據(jù)不同狀態(tài)來顯示不同的視圖
  Widget get _buildWidget {
    switch (widget.state) {
      case LoadState.State_Success:
        return widget.successWidget;
        break;
      case LoadState.State_Error:
        return _errorView;
        break;
      case LoadState.State_Loading:
        return _loadingView;
        break;
      case LoadState.State_Empty:
        return _emptyView;
        break;
      default:
        return null;
    }
  }

  ///加載中視圖
  Widget get _loadingView {
    return Container(
      width: double.infinity,
      height: double.infinity,
      decoration: BoxDecoration(color: Colors.transparent),
      alignment: Alignment.center,
      child: Container(
        height: 80,
        padding: EdgeInsets.all(10),
        decoration: BoxDecoration(
            color: Color(0x88000000), borderRadius: BorderRadius.circular(6)),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: <Widget>[CircularProgressIndicator(), Text('正在加載')],
        ),
      ),
    );
  }

  ///錯誤視圖
  Widget get _errorView {
    return Container(
      width: double.infinity,
      height: double.infinity,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Image.asset(
            'images/img/ic_error_page.png',
            height: 80,
            width: 100,
          ),
          Text("加載失敗,請重試"),
          RaisedButton(
            color: Color(0xffbc2929),
            onPressed: widget.errorRetry,
            child: Text(
              '重新加載',
              style: TextStyle(color: Colors.white),
            ),
          )
        ],
      ),
    );
  }

  ///數(shù)據(jù)為空的視圖
  Widget get _emptyView {
    return Container(
      width: double.infinity,
      height: double.infinity,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Image.asset(
            'images/img/ic_empty.png',
            height: 100,
            width: 100,
          ),
          Padding(
            padding: EdgeInsets.only(top: 10),
            child: Text('暫無數(shù)據(jù)'),
          )
        ],
      ),
    );
  }
}

使用方式

import 'package:flutter/material.dart';
import 'package:sah_flutter/ui/widgets/load_state_layout.dart';

class Test extends StatefulWidget {
  @override
  _TestState createState() => _TestState();
}

class _TestState extends State<Test> {
  //頁面加載狀態(tài),默認為加載中
  LoadState _layoutState = LoadState.State_Loading;

  @override
  void initState() {
    super.initState();
    loadData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('測試LoadStateLayout'),
      ),
      body: LoadStateLayout(
        state: _layoutState,
        errorRetry: () {
          setState(() {
            _layoutState = LoadState.State_Loading;
          });
          loadData();
        }, //錯誤按鈕點擊過后進行重新加載
        successWidget: Center(
          child: Text('加載成功'),
        ),
      ),
    );
  }

  void loadData() {
    //模擬網(wǎng)絡請求
    Future.delayed(Duration(seconds: 2)).then((_) {
      //此為加載結(jié)束
      setState(() {
        //如果加載結(jié)束后的數(shù)據(jù)為空,則狀態(tài)改為空
        _layoutState = LoadState.State_Success;
      });
    }).catchError((_) {
      //此為加載失敗
      setState(() {
        _layoutState = LoadState.State_Error;
      });
    });
  }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容