Flutter 加载中视图失败视图空视图封装

Posted 一叶飘舟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter 加载中视图失败视图空视图封装相关的知识,希望对你有一定的参考价值。

效果

 

实现代码如下

test.dart

import 'dart:io';
import 'dart:math';
import 'package:com/widget/base_layout.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
 
void main() 
  runApp(MaterialApp(
    debugShowCheckedModeBanner: false,
    home: MyApp(),
  ));
  if (Platform.isandroid) 
    SystemUiOverlayStyle systemUiOverlayStyle =
    SystemUiOverlayStyle(statusBarColor: Colors.transparent);
    SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
  

 
class MyApp extends StatefulWidget 
  @override
  _MyAppState createState() => _MyAppState();

 
class _MyAppState extends State<MyApp>
  BaseLayoutStatus status = BaseLayoutStatus.none;
 
  _loadData()
    setState(() 
      status = BaseLayoutStatus.loading;
 
    );
 
    Future.delayed(Duration(seconds: 3),()
      setState(() 
        switch(Random().nextInt(3))
          case 0:
            status = BaseLayoutStatus.fail;
            break;
          case 1:
            status = BaseLayoutStatus.nodata;
            break;
          default:
            status = BaseLayoutStatus.success;
            break;
        
      );
    );
 
  
 
  @override
  Widget build(BuildContext context) 
 
    return Scaffold(
      appBar: AppBar(
        title: Text("页面"),
      ),
      body: BaseLayout(
          layoutType: status,
          callBack: _loadData,
          child: Stack(
            children: <Widget>[
              /*Container(
                decoration: BoxDecoration(
                    image: DecorationImage(
                        image: AssetImage('assets/images/tzd.jpg'),
                        fit: BoxFit.fill)),
              ),*/
              Container(
                width: MediaQuery.of(context).size.width,
                color: Colors.green,
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    SizedBox(
                      width: 200.0,
                      height: 50.0,
                      child: RaisedButton(
                        onPressed: () 
                          _loadData();
                        ,
                        child: Text('点我'),
                      ),
                    ),
                  ],
                ),
              )
            ],
          ),
      ),
    );
  

 


base_layout.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
 
typedef CallBack = void Function();
 
///包含加载中视图 失败视图 没有数据视图 成功视图
class BaseLayout extends StatefulWidget 
  BaseLayoutStatus layoutType = BaseLayoutStatus.none;
  final Widget child;
  CallBack callBack;
  final double opacity;
 
  BaseLayout(@required this.layoutType, @required this.child,this.callBack,this.opacity = 0.5,);
 
  @override
  _BaseLayoutState createState() => _BaseLayoutState();

 
class _BaseLayoutState extends State<BaseLayout>
  @override
  Widget build(BuildContext context) 
    var widgets = <Widget>[];
    widgets.add(widget.child);
    Widget w;
    switch (this.widget.layoutType) 
      case BaseLayoutStatus.loading:
        w = Stack(
          children: <Widget>[
            Opacity(
              child: ModalBarrier(
                dismissible: false,
                color:Color(0xff0b0b0b),
              ),
              opacity: widget.opacity,
            ),
            Container(
              width: MediaQuery.of(context).size.width,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  CupertinoActivityIndicator(
                    radius: 30.0,
                  ),
                  SizedBox(height: 10,),
                  Text(
                    '努力加载中',
                    style: TextStyle(color: Color(0xffffffff),fontSize: 13),
                  ),
                ],
              ),
            ),
          ],
        );
        widgets.add(w);
        break;
      case BaseLayoutStatus.fail:
        w = Container(
          width: MediaQuery.of(context).size.width,
          color: Color(0xff0b0b0b),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Image.asset("assets/images/icon_failedtoload.webp",width: 90,height: 90,),
              SizedBox(height: 15,),
              Text(
                '加载失败',
                style: TextStyle(color: Color(0xff666666),fontSize: 14),
              ),
              SizedBox(height: 10,),
              GestureDetector(
                onTap: ()
                  if(this.widget.callBack!=null)
                    this.widget.callBack();
                ,
                child: Text(
                  '重新加载',
                  style: TextStyle(color: Color(0xff3f54d1),fontSize: 14),
                ),
              ),
            ],
          ),
        );
        widgets.add(w);
        break;
      case BaseLayoutStatus.nodata:
        w = Container(
          width: MediaQuery.of(context).size.width,
          color: Color(0xff0b0b0b),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: <Widget>[
              Image.asset("assets/images/icon_zanwukucun.png",width: 90,height: 90,),
              SizedBox(height: 15,),
              Text(
                '暂时没有数据',
                style: TextStyle(color: Color(0xff666666),fontSize: 14),
              ),
              SizedBox(height: 10,),
              GestureDetector(
                onTap: ()
                  if(this.widget.callBack!=null)
                    this.widget.callBack();
                ,
                child: Text(
                  '刷新',
                  style: TextStyle(color: Color(0xff3f54d1),fontSize: 14),
                ),
              ),
            ],
          ),
        );
        widgets.add(w);
        break;
      case BaseLayoutStatus.success:
      case BaseLayoutStatus.none:
        break;
    
    return Stack(children: widgets);
  

 
enum BaseLayoutStatus 
  loading, //加载中视图
  fail, //失败视图
  nodata, //没有数据视图
  success, //成功加载数据视图
  none //没有状态


 

以上是关于Flutter 加载中视图失败视图空视图封装的主要内容,如果未能解决你的问题,请参考以下文章

Flutter/Dart - 延迟后打开视图

如何在颤动中呈现一个空视图?

空滚动视图和异步加载照片

尝试使用 .nib 加载视图控制器失败

在 ListTile 中打开一个新视图 - Flutter

Xcode Webview 输出“空”