效果
实现代码如下
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 //没有状态 }