banner
MiniKano

MiniKano

This is MiniKano's blog based on Blockchain technology. 新手,请多关照~
github

Flutter對話框

得益於移動端的優勢,flutter 對話框種類還是比較多的,下面列舉幾個比較常用樣式的對話框

需要準備的 Scaffold 組件佈局如下:

Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            title: const Text("對話框"),
        ),
        body: Center(
            child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                    ElevatedButton(
                        onPressed: _alertDailog,
                        child: const Text("alert彈出框-AlertDialog"),
                    ),
                    ElevatedButton(
                        onPressed: _simpleDialog,
                        child: const Text("select彈出框-SumpleDialog"),
                    ),
                    ElevatedButton(
                        onPressed: _modalBottomSheet,
                        child: const Text("model彈出框-modelBottomSheet"),
                    ),
                    ElevatedButton(
                        onPressed: _toast,
                        child: const Text("toast彈出框-toast"),
                    ),
                ]),
        ),
    );
}

AlertDialog(提示對話框)#

提示對話框長這樣:

QQ 截圖 20230407110706.png

//alertDailog(注意異步)
  void _alertDailog() async {
    var result = await showDialog(
        context: context,
        barrierDismissible: false, //不允許點擊灰色背景取消
        builder: (context) {
          return AlertDialog(
            title: const Text("我是alertDialog"),
            content: Text("我是Dialog主體"),
            actions: [
              TextButton(
                  onPressed: () {
                    print("ok");
                    //關閉對話框,直接路由返回就行了
                    Navigator.pop(context, true);
                  },
                  child: const Text("確定")),
              TextButton(
                  onPressed: () {
                    print("cancel");
                    Navigator.pop(context, false);
                  },
                  child: const Text("取消")),
            ],
          );
        });
    print(result);
  }

SimpleDialog#

普通對話框裡面是可以任意放組件的,這裡可以做 select 的功能
s[1].png

void _simpleDialog() async {
    var res = await showDialog(
        context: context,
        builder: (context) {
          return SimpleDialog(
            title: const Text("請選擇語言"),
            children: [
              SimpleDialogOption(
                onPressed: () {
                  Navigator.pop(context, "漢語");
                },
                child: const Text("漢語"),
              ),
              const Divider(),
              SimpleDialogOption(
                onPressed: () {
                  Navigator.pop(context, "英語");
                },
                child: const Text("英語"),
              ),
              const Divider(),
              SimpleDialogOption(
                onPressed: () {
                  Navigator.pop(context, "日語");
                },
                child: const Text("日語"),
              )
            ],
          );
        });
    print(res);
  }

showModalBottomSheet(底部彈出式模態框)#

先看效果:
12[1].png

這裡使用一個購物車案例演示吧:

  void _modalBottomSheet() async {
    var res = await showModalBottomSheet(
        context: context,
        builder: (context) {
          return SizedBox(
            height: 250,
            child: Column(
              children: [
                Padding(
                  padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
                  child: Row(
                    children: [
                      const Padding(
                        padding: EdgeInsets.fromLTRB(0, 0, 10, 0),
                        child: Text(
                          "顏色:",
                          style: TextStyle(fontWeight: FontWeight.bold),
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.all(10),
                        child: ElevatedButton(
                          onPressed: () {
                            Navigator.pop(context, "紅色");
                          },
                          style: ButtonStyle(
                            backgroundColor: const MaterialStatePropertyAll(
                              Color.fromARGB(255, 254, 80, 42),
                            ),
                            shape: MaterialStateProperty.all(
                              RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(50)),
                            ),
                          ),
                          child: const Text("紅色"),
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.all(10),
                        child: ElevatedButton(
                          onPressed: () {
                            Navigator.pop(context, "黃色");
                          },
                          style: ButtonStyle(
                            backgroundColor: const MaterialStatePropertyAll(
                              Color(0x00000ccc),
                            ),
                            shape: MaterialStateProperty.all(
                              RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(50)),
                            ),
                          ),
                          child: const Text("黃色"),
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.all(10),
                        child: ElevatedButton(
                          onPressed: () {
                            Navigator.pop(context, "藍色");
                          },
                          style: ButtonStyle(
                            backgroundColor: const MaterialStatePropertyAll(
                              Color(0x00000ccc),
                            ),
                            shape: MaterialStateProperty.all(
                              RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(50)),
                            ),
                          ),
                          child: const Text("藍色"),
                        ),
                      ),
                    ],
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
                  child: Row(
                    children: [
                      const Padding(
                        padding: EdgeInsets.fromLTRB(0, 0, 10, 0),
                        child: Text(
                          "尺寸:",
                          style: TextStyle(fontWeight: FontWeight.bold),
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.all(10),
                        child: ElevatedButton(
                          onPressed: () {
                            Navigator.pop(context, "XL");
                          },
                          style: ButtonStyle(
                            backgroundColor: const MaterialStatePropertyAll(
                              Color.fromARGB(255, 254, 80, 42),
                            ),
                            shape: MaterialStateProperty.all(
                              RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(50)),
                            ),
                          ),
                          child: const Text("XL"),
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.all(10),
                        child: ElevatedButton(
                          onPressed: () {
                            Navigator.pop(context, "XML");
                          },
                          style: ButtonStyle(
                            backgroundColor: const MaterialStatePropertyAll(
                              Color(0x00000ccc),
                            ),
                            shape: MaterialStateProperty.all(
                              RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(50)),
                            ),
                          ),
                          child: const Text("XML"),
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.all(10),
                        child: ElevatedButton(
                          onPressed: () {
                            Navigator.pop(context, "XXL");
                          },
                          style: ButtonStyle(
                            backgroundColor: const MaterialStatePropertyAll(
                              Color(0x00000ccc),
                            ),
                            shape: MaterialStateProperty.all(
                              RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(50)),
                            ),
                          ),
                          child: const Text("XXL"),
                        ),
                      ),
                    ],
                  ),
                ),
                SizedBox(
                  height: 100,
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Padding(
                        padding: const EdgeInsets.all(10),
                        child: ElevatedButton(
                          onPressed: () {
                            Navigator.pop(context, "ok");
                          },
                          style: ButtonStyle(
                            backgroundColor: const MaterialStatePropertyAll(
                              Colors.red,
                            ),
                            shape: MaterialStateProperty.all(
                              RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(10)),
                            ),
                          ),
                          child: const SizedBox(
                            width: 150,
                            height: 40,
                            child: Center(
                              child: Text("加入購物車"),
                            ),
                          ),
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.all(10),
                        child: ElevatedButton(
                          onPressed: () {
                            Navigator.pop(context, "ok購買");
                          },
                          style: ButtonStyle(
                            backgroundColor: const MaterialStatePropertyAll(
                              Colors.orange,
                            ),
                            shape: MaterialStateProperty.all(
                              RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(10)),
                            ),
                          ),
                          child: const SizedBox(
                            width: 150,
                            height: 40,
                            child: Center(
                              child: Text("立即購買"),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          );
        });
    print(res);
  }

Fluttertoast (氣泡消息)#

注:flutter 沒有自帶 toast,需要去倉庫裝一個

flutter pub add fluttertoast

使用 toast:

 void _toast() {
    Fluttertoast.showToast(
        msg: "toast哦",
        toastLength: Toast.LENGTH_SHORT, //安卓平台有效(toast顯示時長
        gravity: ToastGravity.CENTER, //方位
        timeInSecForIosWeb: 1, //提示時間 針對ios和web
        backgroundColor: Colors.red, //背景顏色
        textColor: Colors.red, //文本顏色
        fontSize: 16.0, //文本字體大小
    );
}

效果:
image-20230407110035977[1].png

自定義 Dailog#

在 Flutter 中,可以通過showDialog中的 builder 函數來添加返回自定義 Widget

//自定義Dialog
void _myDialog() async {
    var res = await showDialog(
        context: context,
        //點擊灰色背景不會消失
        barrierDismissible: false,
        builder: (context) {
            //使用自定義Dailog
            return MyDailog(
                title: "kano",
                content: "kanokano.cn",
                onTap: () {
                    //異步事件
                    Navigator.pop(context, '關閉啦');
                },
            );
        });
    print(res);
}

MyDialog.dart

import 'package:flutter/material.dart';

class MyDailog extends Dialog {
  late String title;
  late String content;
  late Function()? onTap;
  MyDailog(
      {Key? key,
      required this.title,
      required this.content,
      required this.onTap})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    //Material組件可以設置背景透明,所以我們用它
    return Material(
      //設置成透明(順便激活了點擊外側關閉對話框的功能)
      type: MaterialType.transparency,
      //點擊灰色背景不會消失
      child: Center(//包裹一個Center,這樣就不會造成對話框全屏覆蓋了
        child: Container(
            height: 300,
            width: 300,
            padding: const EdgeInsets.all(10),
            color: Colors.white,
            child: Column(
              children: [
                Stack(
                  children: [
                    Align(
                      alignment: Alignment.topLeft,
                      child: Text(title),
                    ),
                    Align(
                      alignment: Alignment.topRight,
                      //InkWell裡面有各種點擊事件和交互事件
                      child: InkWell(
                        onTap: onTap,
                        child: const Icon(Icons.close),
                      ),
                    ),
                  ],
                ),
                const Divider(),
                Container(
                  padding: const EdgeInsets.all(10),
                  width: double.infinity,
                  child: Text(content),
                )
              ],
            )),
      ),
    );
  }
}
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。