美文网首页
Flutter四种页面视图,加载中,无数据,加载失败,成功视图

Flutter四种页面视图,加载中,无数据,加载失败,成功视图

作者: _Insomnia_ | 来源:发表于2019-06-03 20:28 被阅读0次

    我们常常会遇到以下的场景:
    页面已打开,首先需要请求网络,此时页面展示加载中的视图;
    网络请求完毕之后,会出现以下几种情况:

    • 遇到各种问题,出现加载失败的情况,但是又可以重新加载
    • 加载完后无数据,需要展示无数据的属兔
    • 加载成功,展示需要展示的页面

    根据以上场景,我封装了一个自定义组件来满足以上要求

    ///四种视图状态
    enum LoadState { State_Success, State_Error, State_Loading, State_Empty }
    
    ///根据不同状态来展示不同的视图
    class LoadStateLayout extends StatefulWidget {
    
      final LoadState state; //页面状态
      final Widget successWidget;//成功视图
      final VoidCallback errorRetry; //错误事件处理
    
      LoadStateLayout(
          {Key key,
          this.state = LoadState.State_Loading,//默认为加载状态
          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,
        );
      }
    
      ///根据不同状态来显示不同的视图
      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),
                ),
              )
            ],
          ),
        );
      }
    
      ///数据为空的视图
      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('暂无数据'),
              )
            ],
          ),
        );
      }
    }
    

    使用方式

    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> {
      //页面加载状态,默认为加载中
      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() {
        //模拟网络请求
        Future.delayed(Duration(seconds: 2)).then((_) {
          //此为加载结束
          setState(() {
            //如果加载结束后的数据为空,则状态改为空
            _layoutState = LoadState.State_Success;
          });
        }).catchError((_) {
          //此为加载失败
          setState(() {
            _layoutState = LoadState.State_Error;
          });
        });
      }
    }
    

    相关文章

      网友评论

          本文标题:Flutter四种页面视图,加载中,无数据,加载失败,成功视图

          本文链接:https://www.haomeiwen.com/subject/dcphxctx.html