在Flutter利用开发中,常常会遇到自定义弹框的开发需要,如下图所示。
对于这种款式,咱们能够抉择自定义Dialog,具体的款式能够依据本人的须要进行批改。 例如,上面是我的实现,因为文本是一个列表,所以我须要新建一个实体类,如下所示。
class IntroduceModel { int code; List<Data> data; IntroduceModel({this.code, this.data}); IntroduceModel.fromJson(Map<String, dynamic> json) { code = json['code']; if (json['data'] != null) { data = new List<Data>(); json['data'].forEach((v) { data.add(new Data.fromJson(v)); }); } } Map<String, dynamic> toJson() { final Map<String, dynamic> data = new Map<String, dynamic>(); data['code'] = this.code; if (this.data != null) { data['data'] = this.data.map((v) => v.toJson()).toList(); } return data; }}class Data { String itemTitle; String itemContent; Data({this.itemTitle, this.itemContent}); Data.fromJson(Map<String, dynamic> json) { itemTitle = json['itemTitle']; itemContent = json['itemContent']; } Map<String, dynamic> toJson() { final Map<String, dynamic> data = new Map<String, dynamic>(); data['itemTitle'] = this.itemTitle; data['itemContent'] = this.itemContent; return data; }}
而后,咱们自定义一个Dialog,源码如下:
class IntroduceDialog extends Dialog { String des='注:以上的单⽇⽬标额从理论年⽬标额、⽉⽬标额取平均值计算⽽来。'; String title; String content; bool isForce; IntroduceModel model; IntroduceDialog({this.title, this.content,this.isForce}){ if(content!=null){ model=IntroduceModel.fromJson(json.decode(content)); } } @override build(BuildContext context) { return Material( type: MaterialType.transparency, child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ _buildContent(context), _buildClose(context) ], ), ), ); } _buildContent(BuildContext context) { double sWidth= MediaQuery.of(context).size.width; return Container( color: Colors.white, width: sWidth*0.85, height: 420, padding: EdgeInsets.only(left: 15,right: 15,top: 10,bottom: 10), child: SingleChildScrollView( child: Column( children: [ Text(title, style: TextStyle(fontSize: 20,color:Colors.black,fontWeight: FontWeight.bold)), SizedBox(height: 5), _buildListView(), Text(des, style: TextStyle(fontSize: 14)), ], ), ), ); } _buildListView() { return Container( padding: EdgeInsets.only(top: 5,bottom:5,right: 0,), child: ListView.separated( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: model.data.length, separatorBuilder: (BuildContext context, int index) => Container( child: Divider(), ), itemBuilder: (context, index) { return _buildItem(context,model.data, index); }, ), ); } _buildItem(BuildContext context, list, int index) { Data item=list[index]; return Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(item.itemTitle, style: TextStyle(fontSize: 14)), Text(item.itemContent, style: TextStyle(fontSize: 14)), ], ); } _buildClose(BuildContext context) { return GestureDetector( child: Offstage( offstage: isForce, child: Container( margin: EdgeInsets.only(top: 30), child: LoadAssetImage('close_icon', width: 45,height: 45,fit: BoxFit.fill,) ), ), onTap: (){ Navigator.of(context).pop(); }, ); } static showUpdateDialog(BuildContext context, String title,String content, bool isForce) { return showDialog( barrierDismissible: false, context: context, builder: (BuildContext context) { return WillPopScope( child: IntroduceDialog(title: title,content: content, isForce: isForce),onWillPop: _onWillPop); }); } static Future<bool> _onWillPop() async{ return false; }}
须要说的是,自定义的Dialog的根组件须要应用Material,不然的话,Dialog界面的文字上面会呈现黄色的下划线,导致这种状况产生的起因是因为,Text widget 隶属于Material 格调下的组件,如果根节点不是Material 相干组件,则会应用默认带黄色下划线的格局。如果根节点是Material 容器组件,则会采纳其Material格调的款式(即不带有下换线),解决的办法有三个:
解决方案次要有三种:
1,采纳根节点为脚手架Scaffold组件:
Scaffold(body: content,);
2, 采纳根节点为Material 组件。
Material(child: content);
3, 一一批改Text 组件的style 下的decoration为TextDecoration.none。
child: Text( "专栏的文章", overflow: TextOverflow.ellipsis, style: TextStyle( decoration: TextDecoration.none, color: Color(0xFF888888), fontSize: 14, fontWeight: FontWeight.bold, fontFamily: defaultFontFamily, ), )
对于间距,只须要应用Offstage组件即可。最初,在须要应用的中央调用一下这个组件即可,如下所示。
showIntroduceDialog(BuildContext context) async { var localData=await rootBundle.loadString('assets/flow_advertis_funnel.json'); IntroduceDialog.showUpdateDialog(context, '数据阐明', localData, false); }