【问题标题】:How to make a 3 dot pop up menu in app-bar in flutter. Image link is below如何在颤动的应用栏中制作一个 3 点弹出菜单。图片链接如下
【发布时间】:2022-01-16 15:53:58
【问题描述】:

enter image description here根据图片我想在应用程序栏中弹出窗口

【问题讨论】:

  • 分享代码你做了什么
  • 你只想要那个按钮吗?

标签: flutter popup appbar


【解决方案1】:

请参考以下代码

使用 custom_pop_up_menu:^1.2.2

https://pub.dev/packages/custom_pop_up_menu

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<ChatModel> messages;
  List<ItemModel> menuItems;
  CustomPopupMenuController _controller = CustomPopupMenuController();

  @override
  void initState() {
    menuItems = [
      ItemModel('Chat', Icons.chat_bubble),
      ItemModel('Add', Icons.group_add),
      ItemModel('View', Icons.settings_overscan),
    ];
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('CustomPopupMenu'),
        actions: <Widget>[
          CustomPopupMenu(
            child: Container(
              child: Icon(
                Icons.more_horiz,
                color: Colors.white,
                size: 24.0,
              ),
              padding: EdgeInsets.symmetric(
                horizontal: 30.0,
                vertical: 20.0,
              ),
            ),
            menuBuilder: () => ClipRRect(
              borderRadius: BorderRadius.circular(5),
              child: Container(
                color: Colors.white,
                child: IntrinsicWidth(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.stretch,
                    children: menuItems
                        .map(
                          (item) => GestureDetector(
                            behavior: HitTestBehavior.translucent,
                            onTap: _controller.hideMenu,
                            child: Container(
                              height: 40,
                              padding: EdgeInsets.symmetric(horizontal: 20),
                              child: Row(
                                children: <Widget>[
                                  Icon(
                                    item.icon,
                                    size: 15,
                                    color: Colors.black,
                                  ),
                                  Expanded(
                                    child: Container(
                                      margin: EdgeInsets.only(left: 10),
                                      padding:
                                          EdgeInsets.symmetric(vertical: 10),
                                      child: Text(
                                        item.title,
                                        style: TextStyle(
                                          color: Colors.black,
                                          fontSize: 12,
                                        ),
                                      ),
                                    ),
                                  ),
                                ],
                              ),
                            ),
                          ),
                        )
                        .toList(),
                  ),
                ),
              ),
            ),
            pressType: PressType.singleClick,
            verticalMargin: -10,
            controller: _controller,
            barrierColor: Colors.black54,
            horizontalMargin: 0.0,
            arrowColor: Colors.white,
            showArrow: true,
          ),
        ],
      ),
      body: Container(
        child: Center(
          child: Text(
            "Pop up menu",
          ),
        ),
      ),
    );
  }
}

使用弹出菜单按钮的解决方案


Widget popMenus({
  List<Map<String, dynamic>> options,
  BuildContext context,
}) {
  return PopupMenuButton(
    iconSize: 24.0,
    padding: EdgeInsets.zero,
    shape: RoundedRectangleBorder(
      borderRadius: BorderRadius.circular(10.0),
    ),
    icon: Icon(
      Icons.more_horiz_rounded,
      color: Colors.black,
      size: 24.0,
    ),
    offset: Offset(0, 10),
    itemBuilder: (BuildContext bc) {
      return options
          .map(
            (selectedOption) => PopupMenuItem(
              height: 12.0,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    selectedOption['menu'] ?? "",
                    style: TextStyle(
                      fontSize: ScreenUtil().setSp(14.0),
                      fontWeight: FontWeight.w400,
                      fontStyle: FontStyle.normal,
                      color: Colors.blue,
                    ),
                  ),
                  (options.length == (options.indexOf(selectedOption) + 1))
                      ? SizedBox(
                          width: 0.0,
                          height: 0.0,
                        )
                      : Padding(
                          padding: EdgeInsets.symmetric(
                            vertical: 8.0,
                          ),
                          child: Divider(
                            color: Colors.grey,
                            height: ScreenUtil().setHeight(1.0),
                          ),
                        ),
                ],
              ),
              value: selectedOption,
            ),
          )
          .toList();
    },
    onSelected: (value) async {},
  );
}

class PopUpmenusScreen extends StatefulWidget {
  const PopUpmenusScreen({Key key}) : super(key: key);

  @override
  _PopUpmenusScreenState createState() => _PopUpmenusScreenState();
}

class _PopUpmenusScreenState extends State<PopUpmenusScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Examples"),
        actions: [
          Padding(
            padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 4.0,),
            child: popMenus(
              context: context,
              options: [
                {
                  "menu": "option 1" ?? '',
                  "menu_id": 1,
                },
                {
                  "menu": "option 2" ?? "",
                  "menu_id": 2,
                },
                {
                  "menu": "option 3" ?? "",
                  "menu_id": 3,
                },
                {
                  "menu": "option 4" ?? "",
                  "menu_id": 4,
                },
              ],
            ),
          )
        ],
      ),
    );
  }
}

解决方案 2:

 @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Examples"),
        actions: [
          IconButton(
            icon: Icon(
              Icons.more_horiz,
              color: Colors.black,
              size: 20.0,
            ),
            onPressed: () {},
          )
        ],
      ),
    );
  }

【讨论】:

  • 我有检查但我想改变弹出窗口的背景颜色,如图所示。灰色在那里。你也可以查看我更新的图片 i.stack.imgur.com/tiqH3.png
  • 请使用自定义弹出菜单检查编辑后的代码解决方案
【解决方案2】:

试试下面的代码,你会将 SVG 图像存储在图像目录中

actions[
    Padding(
          padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 5),
          child: GestureDetector(
              child: Container(
                decoration: BoxDecoration(
                    shape: BoxShape.circle,
                    border: Border.all(width: 2, color: Colors.blue)),
                child: SvgPicture.asset(
                  "images/ic_more.svg",
                  height: 30,
                  color: Colors.white,
                ),
              ),
              onTapDown: (details) {
                _showPopUpMenu(details.globalPosition);
              })
        )
]

弹出菜单:

_showPopUpMenu(Offset offset) async {
    final screenSize = MediaQuery.of(context).size;
    double left = offset.dx;
    double top = offset.dy;
    double right = screenSize.width - offset.dx;
    double bottom = screenSize.height - offset.dy;

    await showMenu<MenuItemType>(
      context: context,
      position: RelativeRect.fromLTRB(left, top, right, bottom),
      items: MenuItemType.values
          .map((MenuItemType menuItemType) =>
              PopupMenuItem<MenuItemType>(
                value: menuItemType,
                child: Text(getMenuItemString(menuItemType)),
              ))
          .toList(),
    ).then((MenuItemType item) {
      if (item == MenuItemType.EDIT) {
       // here set your route 
      }

    });
  }

以及弹出菜单的枚举数据

import 'package:flutter/foundation.dart';

enum MenuItemType {
  EDIT,
  DUPLICATE
}


getMenuItemString(MenuItemType menuItemType) {
  switch (menuItemType) {
    case MenuItemType.EDIT:
      return "Edit";
    case MenuItemType.DUPLICATE:
      return "Duplicate";
  }
}

【讨论】:

  • 你可以和我分享这个方法 _showPopUpMenu(details.globalPosition .
  • 我会和你分享,但你需要练习
  • 好的,分享给我
  • 更新我的答案请检查。
  • 我有检查但我想改变弹出窗口的背景颜色,如图所示。灰色在那里。你也可以查看我更新的图片i.stack.imgur.com/tiqH3.png
【解决方案3】:

您可以使用 DropdownButton2 轻松做到这一点,这是可自定义的 Flutter 的核心 DropdownButton。

它有customButton 参数,它将用图像、图标或您想要的任何小部件替换普通按钮。您可以使用包中描述的许多选项自定义所有内容并设计您需要的内容。此外,您可以使用offset 参数更改下拉菜单的位置。

这是一个使用 DropdownButton2 作为带有图标的弹出菜单的示例:

class CustomButtonTest extends StatefulWidget {
  const CustomButtonTest({Key? key}) : super(key: key);

  @override
  State<CustomButtonTest> createState() => _CustomButtonTestState();
}

class _CustomButtonTestState extends State<CustomButtonTest> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: DropdownButtonHideUnderline(
          child: DropdownButton2(
            customButton: const Icon(
              Icons.list,
              size: 46,
              color: Colors.red,
            ),
            customItemsIndexes: const [3],
            customItemsHeight: 8,
            items: [
              ...MenuItems.firstItems.map(
                        (item) =>
                        DropdownMenuItem<MenuItem>(
                          value: item,
                          child: MenuItems.buildItem(item),
                        ),
              ),
              const DropdownMenuItem<Divider>(enabled: false, child: Divider()),
              ...MenuItems.secondItems.map(
                        (item) =>
                        DropdownMenuItem<MenuItem>(
                          value: item,
                          child: MenuItems.buildItem(item),
                        ),
              ),
            ],
            onChanged: (value) {
              MenuItems.onChanged(context, value as MenuItem);
            },
            itemHeight: 48,
            itemWidth: 160,
            itemPadding: const EdgeInsets.only(left: 16, right: 16),
            dropdownPadding: const EdgeInsets.symmetric(vertical: 6),
            dropdownDecoration: BoxDecoration(
              borderRadius: BorderRadius.circular(4),
              color: Colors.redAccent,
            ),
            dropdownElevation: 8,
            offset: const Offset(0, 8),
          ),
        ),
      ),
    );
  }
}

class MenuItem {
  final String text;
  final IconData icon;

  const MenuItem({
    required this.text,
    required this.icon,
  });
}

class MenuItems {
  static const List<MenuItem> firstItems = [home, share, settings];
  static const List<MenuItem> secondItems = [logout];

  static const home = MenuItem(text: 'Home', icon: Icons.home);
  static const share = MenuItem(text: 'Share', icon: Icons.share);
  static const settings = MenuItem(text: 'Settings', icon: Icons.settings);
  static const logout = MenuItem(text: 'Log Out', icon: Icons.logout);

  static Widget buildItem(MenuItem item) {
    return Row(
      children: [
        Icon(
                item.icon,
                color: Colors.white,
                size: 22
        ),
        const SizedBox(
          width: 10,
        ),
        Text(
          item.text,
          style: const TextStyle(
            color: Colors.white,
          ),
        ),
      ],
    );
  }

  static onChanged(BuildContext context, MenuItem item) {
    switch (item) {
      case MenuItems.home:
      //Do something
        break;
      case MenuItems.settings:
      //Do something
        break;
      case MenuItems.share:
      //Do something
        break;
      case MenuItems.logout:
      //Do something
        break;
    }
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-09
    • 2021-02-14
    • 1970-01-01
    • 1970-01-01
    • 2020-06-11
    • 2022-12-13
    • 1970-01-01
    相关资源
    最近更新 更多