精华内容
参与话题
问答
  • flutter 自定义弹框

    2020-04-18 17:54:36
    自定义弹框 在Material组件中定义内容,这样能实现弹框出现屏幕透明的效果 1、定义组件类来继承Dialog,添加build方法,return 自定义内容 2、通过 showDialog方法调用弹出框 showDialog( context: ...
    自定义弹框
    	在Material组件中定义内容,这样能实现弹框出现屏幕透明的效果
    		
    	1、定义组件类来继承Dialog,添加build方法,return 自定义内容
    	2、通过 showDialog方法调用弹出框
    	
    	    showDialog( 
    	      context: context,
    	      builder: (context){
    	        return 类组件名();
    	      }
    	    ).then((value){
    	     	参数为Navigator.pop(context,参数)传递的参数
    	    });
    	    
    	3、关闭弹框并传递参数
    	
    		回调函数中设置
    			Navigator.pop(context,参数)传递的参数;
    

    代码示例:

    import 'dart:async';
    
    import 'package:flutter/material.dart';
    import 'package:date_format/date_format.dart';
    import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart';
    import 'package:flutter_swiper/flutter_swiper.dart';
    import 'package:fluttertoast/fluttertoast.dart';
    import 'package:myflutter/page/me.dart';
    
    
    class Home4 extends StatefulWidget {
      Home4({Key key}) : super(key: key);
    
      @override
      _Home2State createState() => _Home2State();
    }
    
    class _Home2State extends State<Home4> {
    
      @override
      void initState() { 
        super.initState();
      }
    
    //回调触发弹框
      show()
      {
        //Future类型,then或者await获取
        showDialog( 
          context: context,
          builder: (context){
            return Log();
          }
        ).then((value){
          print("$value");
        });
      }
    
    
      @override
      Widget build(BuildContext context) {
        return Container(
           child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
             children: <Widget>[
               
              RaisedButton(
                child: Text('自定义弹出框'),
                color: Theme.of(context).accentColor,
                onPressed: (){
                  show();
                },
              ),
    
    
           ]),
        );
      }
    }
    
    class Log extends Dialog{
    
      timer(context)
      {
        var time=Timer.periodic(
          Duration(milliseconds: 1500),
          (t){
            print('执行');
            Navigator.pop(context);
            t.cancel();
          }
        );
      }
    
      @override
      Widget build(BuildContext context) {
    
         timer(context);
    	
    	//自定义弹框内容
        return Material(
          
          type:MaterialType.transparency,
          child: Center(
            
            child:Container(
              height: 300,
              width: 300,
              color: Colors.white,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.start,
                children: <Widget>[
                  Padding(
                    padding: EdgeInsets.all(20),
                    child: Stack(
                      children: <Widget>[
                        Align(
                          child: Text('提示'),
                          alignment:Alignment.center,
                        ),
                        Align(
                          alignment: Alignment.centerRight,
                          child: InkWell(
                            child: Icon(Icons.confirmation_number),
                            onTap: (){
                              Navigator.pop(context,'guanbi');
                            },
                          ),
                        ),
                        
                      ],
                    )
                  ),
                  Divider(),
                  Container(
                    padding: EdgeInsets.all(10),
                    width: double.infinity,
                    child: Text('啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊哈哈哈哈哈哈',textAlign: TextAlign.left,),
                  )
                ],
              ),
           )
          ),
        );
      }
    }
    
    // 因为表单组件需要改变状态,所以要使用有状态组件
    
    /*
    
    轮播图必须外包一层有高度的父容器或者使用子元素宽高比组件AspectRatio
    
    
     */
    

    效果图:
    在这里插入图片描述

    展开全文
  • Flutter自定义弹框

    2020-08-28 21:03:10
    导致这种情况发生的原因是因为,Text widget 隶属于Material 风格下的组件,如果根节点不是Material 相关组件,则会使用默认带黄色下划线的格式。如果根节点是Material 容器组件,则会采用其Material风格的样式(即...

    在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);
      }
    
    展开全文
  • Flutter应用开发中,经常会遇到自定义弹框的开发需求,如下图所示。 对于这种样式,我们可以选择自定义Dialog,具体的样式可以根据自己的需要进行修改。 例如,下面是我的实现,由于文本是一个列表,所以我需要...

    在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);
      }
    

    感谢阅读

    博主在此给大家安利一款分享学习资料的app,此app的主要就是收集了互联网上的各种学习资料做整合并免费分享。里面涵盖了Android、java、python、数据结构、算法、前端、爬虫、大数据、深度学习、UI等等技术,包含M课网课程、某课堂VIP课程、各培训机构课程、某鱼的一些付费课程以及算法面试资料,并且正在不断更新中,你想要的学习资料几乎都有,当然你也可以加入我们的技术Q群获取资料:687667883,任何课程问题可直接咨询群主。
    目前对接的课程论坛如下,您可以提前了解下有哪些课程:
    链接资源如下:
        享学app资源对接论坛一(IT码上发)
        享学app资源对接论坛二(学途无忧)
    download地址如下:
    下载二维码_1.0.0版本.png

    展开全文
  • AlertDialog 确定取消通用 弹框,长按 _alertDioalog () async { var result= await showDialog( context: context, builder: (context)=>AlertDialog( title: Text('提示信息'), content: ...

    AlertDialog

    确定取消通用 弹框,长按

      _alertDioalog () async {
        var result= await  showDialog(
          context: context,
          builder:  (context)=>AlertDialog(
            title: Text('提示信息'),
            content: Text('您确定要删除吗'),
            actions: <Widget>[
              FlatButton(onPressed: (){
                Navigator.pop(context,'0');
              }, child: Text('取消')),
              FlatButton(onPressed: (){
                 Navigator.pop(context,'1');
              }, child: Text('确定',))
            ],
          ));
          print(result);
      }
    

    SimpleDialog

    方案选择通用弹框

    _simpleDialog () async {
        var result= await  showDialog(
          context: context,
          builder: (context)=>SimpleDialog(
          title:new Text('请选择'),
          children: <Widget>[
            SimpleDialogOption(
              child: new Text('方案一'),
              onPressed: (){
                Navigator.pop(context,1);
            }),
            Divider(),
            SimpleDialogOption(
              child: new Text('方案二'),
              onPressed: (){
                 Navigator.pop(context,2);
            }),
            Divider(),
            SimpleDialogOption(
              child: new Text('方案三'),
              onPressed: (){
                 Navigator.pop(context,3);
            }),
          ])
        );
    

    showModalBottomSheet

    底部弹框,可以用来作为分享,底部自定义公功能,方案选择等等

    _modeBottomSheet () async {
        var reslut= await showModalBottomSheet(
          context: context, 
          builder: (context)=>Container(
            height: 200,
            child: Column(
              children:<Widget>[
                ListTile(
                  title: new Text('分享 A'),
                  onTap: (){
                    Navigator.pop(context,'A');
                  },
                ),
                Divider(height: 3,),
                ListTile(
                  title: new Text('分享 B'),
                  onTap: (){
                    Navigator.pop(context,'B');
                  },
                ),
                Divider(),
                ListTile(
                  title: new Text('分享 C'),
                  onTap: (){
                    Navigator.pop(context,'C');
                  },
                ),
              ]
            ),
          )
        );
        print(reslut);
      }
    

    toast插件

    用来登陆注册成功,操作成功或者失败给的提示信息

    _toast() {
        Fluttertoast.showToast(
            msg: "操作成功",//提示信息
            toastLength: Toast.LENGTH_SHORT,//大小
            gravity: ToastGravity.BOTTOM,//方位
            timeInSecForIos: 1,//ios可以设置时间
            backgroundColor: Colors.black,//背景颜色
            textColor: Colors.white,
            fontSize: 16.0
        );
      }
    

    自定义Dialog

    ShowDialog里面的widget默认会铺满整个屏幕,如果想采用Dialog风格的弹出框,我们需要去创建一个继承Dialog的类,重写Build方法

    import 'package:flutter/material.dart';
    import 'dart:async';
    class CustomDialog extends Dialog {
      _showTimer(BuildContext context){
        Timer.periodic(Duration(milliseconds: 3000), (t){
          print('3秒后触发');
          Navigator.pop(context);
          t.cancel();//关闭定时器
        });
      }
      @override
      Widget build(BuildContext context){
        _showTimer(context);
        return Material(
          type : MaterialType.transparency,
          child : Center(
            child: Container(
              width: 300,
              height: 300,
              color: Colors.white,
              child: Column(children: <Widget>[
              Padding(padding: EdgeInsets.all(10.0),
                child: Stack(
                  children:<Widget>[
                    Align(
                      child:Text ('关于我们'),
                      alignment: Alignment.center,
                    ),
                    Align(
                      child: InkWell(
                        child:Icon(Icons.close),
                        onTap: (){
                          print('colse');
                          Navigator.pop(context,'colse');
                        },
                      ),
                      alignment: Alignment.centerRight,
                    )
                  ],
                ),
              ),
              Divider(),
              Container(
                padding: EdgeInsets.all(10),
                width: double.infinity,
                child:new Text('嘎嘎嘎',textAlign:TextAlign.left)
              )
              ],),
            )
          ),
        );
      }
    }
    
    展开全文
  • 自定义Flutter loading弹框

    千次阅读 2019-09-28 16:01:25
    Flutter中,万物皆widget。所以这所谓的弹框其实也是一个widget。 而现实弹框其实就是打开一个新的路由,只不过背景颜色设为透明色就行了。 布局代码 实现代码如下: class LoadingDialog extends Dialog { @...
  • Flutter实现自定义底部弹框分享

    千次阅读 2019-07-10 00:04:17
    flutter的这种弹框,我们用到了showModalBottomSheet这个类,有一篇比较详细的文章Flutter 19: 图解【分享页面】底部对话框,使用的是这个类,说得挺详细的 另外把从发布按钮的代码给全部放上来。 void showPub() {...
  • Flutter 自定义Dialog

    2019-06-12 11:10:02
    因为要实现这个效果 自定义了一个Dialog...///自定义弹框 class MyDialog extends Dialog { MyDialog({ Key key, }) : super(key: key); @override Widget build(BuildContext context) { double screenWidth...
  • * 自定义Loading等待弹框 * @params text 提示内容 */ class LoadingDialog extends Dialog { final String text; LoadingDialog({Key key, @required this.text}) : super(key: key); @override Widget bu
  • Flutter - showModalBottomSheet自定义bottom弹框代码撂这儿了 代码撂这儿了 import 'package:flutter/material.dart'; class AlertGridItem extends Object { final String title; final int codePoint; // ...
  • 1、弹框整体实现 和写界面是一样的 毕竟flutter中 一切皆组件 界面 弹框 按钮。。。。都是组件 2、样式和跳转要进行处理 背景色透明效果有两种实现方式 a、界面跳转中opaque: false可以设置下个界面背景透明 b、使用...
  • 实现一个弹框有两种方式,一种是继承于 Dialog 来定义一个子类实现弹框效果,一种是创建一个 新的 StatelessWidget(页面)。 实际上 Flutter 提供的 Dialog 也是继承于 StatelessWidget而实现的。 1 自定义 Dialog ...
  • 如图: 项目需求需要实现以上效果 思路解析: 1 可以用dialog来实现 2 可以用一个新statfulWidget实现 .../// 描述:设置密码弹框功能 /// crated by xudailong on 2020/3/10. /// class MineDestoryS...
  • AlertDialog dialog弹框 在 showDialog中 定义 AlertDialog _alertDialog () async { var result = showDialog<void>( context: context, barrierDismissible: true, // false = user mu...
  • 自定义带删除按钮的搜索框的时候,给输入框增加了内容控制器后,导致键盘隐藏或者展示loading框的时候内容自动被清空了,并且监听onChange没有变化,内容如下: ... TextEditingController _...

空空如也

1 2
收藏数 36
精华内容 14
关键字:

flutter 自定义弹框