弹出菜单
PopupMenuButton
使用PopupMenuButton,点击时弹出菜单
Center(
        child: PopupMenuButton<String>(
      initialValue: 'Math', // 初始值
      itemBuilder: (context) {
        // 子项构造函数
        return <PopupMenuEntry<String>>[
          const PopupMenuItem(value: 'Chinese', child: Text('语文')),
          const PopupMenuItem(value: 'Math', child: Text('数学')),
        ];
      },
    ));

 选中与未选中事件
 onSelected: (value) {
   print("选中了${value}");
 },
 onCanceled: () {
   print("一个未选中时触发");
 },
长按提示
tooltip: '这是PopupMenuButton组件',

设置显示内容
 默认情况下是显示三个点,但是也可以设置为文字或图标。child 和 icon 这两个属性不能再PopupMenuButton中共存
// 文字
child: const Text('学科'),
// 图标
icon: const Icon(Icons.add),
边框
 shape: RoundedRectangleBorder(
       side: const BorderSide(color: Colors.blue),
       borderRadius: BorderRadius.circular(10)
     ),

PopupMenuItem
PopupMenuItem菜单子项,有以下几个属性:
- value,选中的值
- enabled,是否可选
- height,高度
- textStyle,文本样式
- child,子控件
PopupMenuDivider
PopupMenuDivider是菜单分割线,插入在下拉项之间
itemBuilder: (context) {
   // 子项构造函数
   return <PopupMenuEntry<String>>[
     const PopupMenuItem(value: 'Chinese', child: Text('语文')),
     const PopupMenuDivider(),
     const PopupMenuItem(value: 'Math', child: Text('数学')),
   ];
 },
showMenu
 Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () async {
        var value = await showMenu(
          context: context,
          position: const RelativeRect.fromLTRB(1000, 1000, 0, 0),
          items: [
            const PopupMenuItem(
              value: 1,
              child: Text('菜单项1'),
            ),
            const PopupMenuItem(
              value: 2,
              child: Text('菜单项2'),
            ),
          ],
        );
        print("选中的菜单是$value");
      },
      child: const Text('点击弹出菜单'),
    );
  }

弹出提示
一般用于二次确认提示,防止误操作。
AlertDialog
ElevatedButton(
      onPressed: () {
        showDialog(
            context: context,
            barrierDismissible: false, // 点击空白处是否可以关闭
            builder: (BuildContext context) {
              return AlertDialog(
                title: const Text("提示"),
                content: const Text("是否确认删除?"),
                actions: [
                  TextButton(
                      onPressed: () {
                        Navigator.of(context).pop(); // 关闭AlertDialog弹窗
                        print("取消删除");
                      },
                      child: const Text("取消")),
                  TextButton(
                      onPressed: () {
                        Navigator.of(context).pop(); // 关闭AlertDialog弹窗
                        print("确认");
                      },
                      child: const Text("确认"))
                ],
              );
            });
      },
      child: const Text('删除'),
    );

 获取用户点击的哪一个
 onPressed: () async {
    var result = await showDialog(
    ...
SimpleDialog
return ElevatedButton(
      onPressed: () {
        showDialog(
            context: context,
            barrierDismissible: false, // 点击空白处是否可以关闭
            builder: (BuildContext context) {
              return SimpleDialog(
                title: const Text('提示'),
                children: <Widget>[
                  Container(
                    height: 80,
                    alignment: Alignment.center,
                    child: const Text('确认删除吗?'),
                  ),
                  const Divider(height: 1,),
                  TextButton(
                    child: const Text('取消'),
                    onPressed: () {
                      Navigator.of(context).pop('cancel');
                    },
                  ),
                  const Divider(height: 1,),
                  TextButton(
                    child: const Text('确认'),
                    onPressed: () {
                      Navigator.of(context).pop('ok');
                    },
                  ),
                ],
              );
            });
      },
      child: const Text('删除'),
    );

Dialog
如果你觉得这还是不够个性,那可以祭出终极大招了,直接使用Dialog,Dialog可以定制任何对话框
class _YcHomeBodyState extends State<YcHomeBody> {
  final String appName = '王者农药';
  final String appIcon =
      'https://img.ixintu.com/upload/jpg/20210523/f083ac25b8d57debcda7653a524c0026_257819_800_800.jpg!ys';
  
  Widget build(BuildContext context) {
    return ElevatedButton(
        child: const Text('卸载'),
        onPressed: () {
          showDialog(
            context: context,
            barrierDismissible: false, // 点击空白处是否可以关闭
            builder: (BuildContext context) {
              return Dialog(
                //形状
                shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(16)),
                //阴影
                elevation: 2,
                //背景色
                backgroundColor: Colors.transparent,
                // 弹窗具体显示的东西
                child: Container(
                  padding: const EdgeInsets.all(16),
                  // 修饰
                  decoration: BoxDecoration(
                    color: Colors.white,
                    borderRadius: BorderRadius.circular(16),
                  ),
                  child: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      // 标题
                      Text("要卸载 “$appName” 吗 ?",
                          style: const TextStyle(fontSize: 16)),
                      // 用于占位
                      const SizedBox(
                        height: 16,
                      ),
                      //内容
                      Text("卸载 “$appName“ 将同时删除其数据",
                          style: const TextStyle(fontSize: 12)),
                      const SizedBox(
                        height: 16,
                      ),
                      // app图标,使用ClipRRect对图片进行裁剪
                      ClipRRect(
                        borderRadius: BorderRadius.circular(10),
                        child: Image.network(
                          appIcon,
                          width: 50,
                          height: 50,
                        ),
                      ),
                      //  底部两个按钮
                      const SizedBox(
                        height: 10,
                      ),
                      Row(
                        // 设置横向自动分配剩余控件
                        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                        children: [
                          TextButton(
                              onPressed: () {
                                print("取消");
                                Navigator.of(context).pop();
                              },
                              child: const Text("取消")),
                          // 分割线
                           const SizedBox(
                             height: 20,
                             width: 20,
                             child:    VerticalDivider(
                               width: 20,
                               thickness: 2,
                               color: Colors.grey,
                             ),
                           ),
                          TextButton(
                              onPressed: () {
                                print("卸载");
                                Navigator.of(context).pop();
                              },
                              child: const Text(
                                "卸载",
                                style: TextStyle(color: Colors.red),
                              ))
                        ],
                      )
                    ],
                  ),
                ),
              );
            },
          );
        });
  }
}



















