Flutter-弹框

作者: 秋分落叶 | 来源:发表于2019-08-20 15:47 被阅读37次

    对话框作为一个挺重要的东西,这里来说一下,细细一数也蛮多的,本文包括

    [1].SimpleDialog
    [2].AlertDialog
    [3].CupertinoAlertDialog
    [4].Dialog中的组件状态更新
    [5].SnackBar
    [6].BottomSheet
    [7].DatePicker
    [8].TimePickerwTimePicker,
    [9].CupertinoPicker
    [10].CupertinoDatePicker
    [11].CupertinoTimerPicker
    复制代码
    

    0.搭个场子再说
    class DialogShow extends StatefulWidget {
      @override
      _DialogShowState createState() => _DialogShowState();
    }
    
    class _DialogShowState extends State<DialogShow> {
      @override
      Widget build(BuildContext context) {
        var title = Container(
          alignment: AlignmentDirectional.center,
          child: Text(
            "Dialog Unit",
            style: TextStyle(fontSize: 30),
          ),
        );
    
        Map<String, Function> buttons = {
          "对话框SimpleDialog": _showSimpleDialog,
          "对话框AlertDialog": _showAlertDialog,
          "对话框CupertinoAlertDialog": _showCupertinoAlertDialog,
          "对话框显示自己": _showWidgetDialog,
          "对话框显示StatefulWidget": _showStatefulWidgetDialog,
          "Scaffold": _showScaffold,
          "BottomSheet": _showBottomSheet,
          "DatePicker": _showDatePicker,
          "TimePicker": _showTimePicker,
          "CupertinoPicker": _showCupertinoPicker,
          "CupertinoDatePicker": _showCupertinoDatePicker,
          "CupertinoTimerPicker": _showCupertinoTimerPicker,
        };
    
        var btns=  buttons.keys.toList().map((str){//构建按钮组件列表
          return RaisedButton(
            onPressed: () {
              buttons[str](context);
            },
            child: Text(str),
          );
        }).toList();
    
        var result =Column(children: <Widget>[title,Column(
          children: btns,
        )],) ;
        return result;
      }
    }
    复制代码
    

    1.对话框:SimpleDialog

    通过showDialog来创建对话框,传入BuildContext对象,通过builder构造器来创建组件
    简单的对话框,只要一条条的东西可以选择SimpleDialog,比如:

    image
    _showSimpleDialog(BuildContext context) {
      var strs=['云深不知处内亥时息,卯时起',
        "云深不知处内不可挑食留剩,不可境内杀生",
        "云深不知处内不可私自斗殴,不可淫乱",
        "云深不知处禁止魏无羡入内,不可吹笛"];
    
      var title = Row(//标题
        children: <Widget>[
          Image.asset("images/icon_lwj.png", width: 30,height: 30,),
          SizedBox(width: 10,),
          new Text("蓝氏家规")],
      );
      showDialog(
          context: context,
          builder: (context) {
            return SimpleDialog(
              title: title,
              children: strs.map((str){
                return SimpleDialogOption(
                  child: Row(children: <Widget>[
                    Icon(Icons.turned_in_not,color: Colors.blue,),Text(str)],) ,
                  onPressed: () {
                    Navigator.of(context).pop(str);
                    print(str);
                  },
                );
              }).toList(),
            );
          });
    }
    复制代码
    

    3.对话框:AlertDialog

    AlertDialog组件包括标题(title)、内容(content)、actions(行为),还有一些阴影,颜色形状等辅助属性。

    image
      _showAlertDialog(BuildContext context) {
        var title = Row(//标题
          children: <Widget>[
            Image.asset("images/icon_wwx.png", width: 30,height: 30,),
            SizedBox(width: 10,),
            new Text("表白")],
        );
        var content = Row(//内容
          children: <Widget>[
            Text("我💖你,你是我的"),
            Image.asset("images/icon_ylm.png",width: 30, height: 30, )],
        );
    
        showDialog(
            context: context,
            builder: (context) => //构造器
                AlertDialog(title: title, content: content, actions: <Widget>[
                  FlatButton(
                    child: Text("不要闹"),
                    onPressed: () {
                      Navigator.of(context).pop();
                    },
                  ),
                  FlatButton(
                    child: Text("走开"),
                    onPressed: () {
                      Navigator.of(context).pop();
                    },
                  )
                ]));
      }
    复制代码
    

    3.对话框:CupertinoAlertDialog

    Cupertino风格的对话框

    image
    void _showCupertinoAlertDialog(BuildContext context) {
      var title = Row(//标题
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Image.asset("images/icon_wwx.png", width: 30,height: 30,),
          SizedBox(width: 10,),
          new Text("表白")],
      );
      var content = Row(
        children: <Widget>[
          Text("我💖你,你是我的",style: TextStyle(fontSize: 20),),
          Image.asset("images/icon_ylm.png", width: 40, height: 40, ) ],
      );
      var dialog = CupertinoAlertDialog(
        content: content,
        title: title,
        actions: <Widget>[
          CupertinoButton( child: Text("不要闹"),
            onPressed: () {
              Navigator.pop(context);
            },
          ),
          CupertinoButton( child: Text("走开"),
            onPressed: () {
              Navigator.pop(context);
            },
          ),
        ],
      );
      showDialog(context: context, builder: (context) => dialog);
    }
    复制代码
    

    4.瞎玩一下

    既然对话框里面显示的是一个Widget,那我把它自己显示出了会怎么样?
    现在Dialog应该不难玩了吧,既然什么Widget都能放进去,还有什么好怕的。

    image
    _showWidgetDialog(BuildContext context) {
      showDialog(
          context: context,
          builder: (context) {
            return this.widget;
          });
    }
    复制代码
    

    5.对话框中的StatefulWidget

    想要更新对话框里的组件状态,可以用StatefulBuilder,里面回调的StateSetter对象

    image
    _showStatefulWidgetDialog(BuildContext context) {
      var progress = 0.0;
      StateSetter stateSetter;
    
      Timer.periodic(Duration(milliseconds: 100), (timer) {//计时器模拟进度增加
        progress += 0.1;
        if (stateSetter != null) {
          stateSetter(() {});
        }
        if (progress >= 1) {
          timer.cancel();
          stateSetter = null;
          Navigator.of(context).pop();
        }
      });
    
      var statefulBuilder = StatefulBuilder(
        builder: (ctx, state) {
          stateSetter = state;
          return Center(
            child: SizedBox(width: 150, height: 150,
              child: Card(elevation: 24.0,
                color: Colors.blue.withAlpha(240),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: <Widget>[
                    CircularProgressIndicator(
                      valueColor: AlwaysStoppedAnimation(Colors.white),
                      value: progress,
                    ),
                    SizedBox(height: 20,),
                    Text("Loading...",
                      style: TextStyle(color: Colors.white),),
                    SizedBox(height: 5,),
                    Text("done ${((progress-0.1) * 100).toStringAsFixed(1)}%",
                      style: TextStyle(color: Colors.white),),
                  ],
                ),
              ),
            ),
          );
        },
      );
      showDialog(context: context, builder: (ctx) => statefulBuilder);
    }
    复制代码
    

    6.底部弹框:SnackBar

    这个比较简单,使用Scaffold.of方法获取ScaffoldState调用showSnackBar

    image
    _showScaffold(BuildContext context) {
          var snackBar = SnackBar(
          backgroundColor: Color(0xffFB6431),//颜色
          content: Text('Hello!'),//内容
          duration: Duration(seconds: 3),//持续时间
          action: SnackBarAction(
              label: '确定',
              onPressed: () {
                print("Flutter之旅");
              }));
          Scaffold.of(context).showSnackBar(snackBar);//这样就行了
    }
    复制代码
    

    7.底部抽屉:BottomSheet

    用法和SnackBar相似,更强的是底部栏的child你想放什么都可以。

    image
    bool _showing=false;
    _showBottomSheet(BuildContext context) {
      var bottomSheet = BottomSheet(
          onClosing: () {},
          builder: (context) => (Container(
                color: Color(0xdde3fbf6),
                height: 150,
                child: Center(
                  child: Image.asset("images/wy_300x200_filter.jpg"),
                ),
              )));
      if(_showing){
        Navigator.of(context).pop();
      }else{
        Scaffold.of(context).showBottomSheet(bottomSheet.builder); //这样就行了
      }
      _showing=!_showing;
    }
    复制代码
    

    8.日历选表:showDatePicker

    返回一个DataTime泛型的Future对象

    image
    void _showDatePicker(BuildContext cxt) {
      showDatePicker(
        context: cxt,
        initialDate: DateTime.now(),
        firstDate: DateTime(2018),
        lastDate: DateTime(2030),
        builder: (BuildContext context, Widget child) {
          return Theme(
            data: ThemeData.dark(),
            child: child,
          );
        },
      ).then((data){
        print(data);
      });
    }
    复制代码
    

    9.时间选表:showDatePicker

    返回一个TimeOfDay泛型的Future对象

    image
    void _showTimePicker(BuildContext cxt) {
      showTimePicker(
        context: cxt,
        initialTime: TimeOfDay(hour: 11, minute: 45),
        builder: (BuildContext context, Widget child) {
          return Theme(
            data: ThemeData.dark(),
            child: child,
          );
        },
      ).then((data){
        print(data);
      });
    }
    复制代码
    

    10.选择表:CupertinoPicker

    ios风格的选择表,感觉还挺好看

    image
    void _showCupertinoPicker(BuildContext context){
      var names=['魏祖','蓝二','江姐','江舅','瑶妹'];
      final picker  = CupertinoPicker(
          itemExtent: 40,
          onSelectedItemChanged: (position){
            print('The position is ${names[position]}');
          }, children: names.map((e){
            return Text(e);
      }).toList());
      showCupertinoModalPopup(context: context, builder: (cxt){
        return Container(
          height: 200,
          child: picker,
        );
      });
    }
    复制代码
    

    11.日期选卡:CupertinoPicker

    挺方便的

    image
    _showCupertinoDatePicker(BuildContext context){
      final picker =CupertinoDatePicker(
        onDateTimeChanged: (date){
        print("当前日期、时间 ${date.toString()}");
      },
        initialDateTime: DateTime(1994),
      );
      showCupertinoModalPopup(context: context, builder: (cxt){
        return Container(
          height: 200,
          child: picker,
        );
      });
    }
    复制代码
    

    12.日期选卡:CupertinoPicker

    不多说,看效果

    image
    void _showCupertinoTimerPicker(BuildContext cxt){
      final picker = CupertinoTimerPicker(onTimerDurationChanged: (duration){
        print('当前时间 $duration');
      });
      showCupertinoModalPopup(context: cxt, builder: (cxt){
        return Material(child: Container(
          height: 200,
          child: picker,
        ),);
      });
    }
    复制代码
    

    好了,本文就到这里。


    结语

    链接:https://juejin.im/post/5d4bb7926fb9a06b084ce1d0

    相关文章

      网友评论

        本文标题:Flutter-弹框

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