如何设置 Flutter showMenu 起点

Aym*_*out 4 flutter flutter-layout

我想知道如何更改 的原点popUpMenu,在底部应用栏正上方启动弹出窗口,无论项目数如何。与屏幕右端对齐。类似的东西(例如)

Positioned(right: 0, bottom: bottomAppBarHeight)
Run Code Online (Sandbox Code Playgroud)

这是popUpMenu我想要实现的设计布局的截图:

设计

这是当前放置的屏幕截图popUpMenu(请忽略其他设计差异,因为它们无关紧要):

实际的

使用的代码如下:

                      onPressed: () {
                        final RelativeRect position =
                            buttonMenuPosition(context);
                        showMenu(context: context, position: position, items: [
                          PopupMenuItem<int>(
                            value: 0,
                            child: Text('Working a lot harder'),
                          ),
                          PopupMenuItem<int>(
                            value: 1,
                            child: Text('Working a lot less'),
                          ),
                          PopupMenuItem<int>(
                            value: 1,
                            child: Text('Working a lot smarter'),
                          ),
                        ]);
                      },
Run Code Online (Sandbox Code Playgroud)

buttonMenuPosition函数的代码:

RelativeRect buttonMenuPosition(BuildContext context) {
    final bool isEnglish =
        LocalizedApp.of(context).delegate.currentLocale.languageCode == 'en';
    final RenderBox bar = context.findRenderObject() as RenderBox;
    final RenderBox overlay =
        Overlay.of(context).context.findRenderObject() as RenderBox;
    const Offset offset = Offset.zero;
    final RelativeRect position = RelativeRect.fromRect(
      Rect.fromPoints(
        bar.localToGlobal(
            isEnglish
                ? bar.size.centerRight(offset)
                : bar.size.centerLeft(offset),
            ancestor: overlay),
        bar.localToGlobal(
            isEnglish
                ? bar.size.centerRight(offset)
                : bar.size.centerLeft(offset),
            ancestor: overlay),
      ),
      offset & overlay.size,
    );
    return position;
  }
Run Code Online (Sandbox Code Playgroud)

更改偏移量不起作用。

Dan*_*cia 7

我能够得到类似的行为,如下所示:

    class _SettingsPopupMenuState extends State<SettingsPopupMenu> {
      static const Map<String, IconData> _options = {
       'Settings' : Icons.favorite_border,
       'Share'    : Icons.bookmark_border,
       'Logout'   : Icons.share,
      };

      void _showPopup(BuildContext context) async {
        //*get the render box from the context
        final RenderBox renderBox = context.findRenderObject() as RenderBox;
        //*get the global position, from the widget local position
        final offset = renderBox.localToGlobal(Offset.zero);

        //*calculate the start point in this case, below the button
        final left = offset.dx;
        final top = offset.dy + renderBox.size.height;
        //*The right does not indicates the width
        final right = left + renderBox.size.width;

        //*show the menu
        final value = await showMenu<String>(
          // color: Colors.red,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(20.0)
          ),
          context: context, 
          position: RelativeRect.fromLTRB(left, top, right, 0.0), 
          items: _options.entries.map<PopupMenuEntry<String>>((entry) {
            return PopupMenuItem(
              value: entry.key,
              child: SizedBox(
                // width: 200, //*width of popup
                child: Row(
                  children: [
                    Icon(entry.value, color: Colors.redAccent),
                    const SizedBox(width: 10.0),
                    Text(entry.key)
                  ],
                ),
              ),
            );
          }).toList()
        );

        print(value);
      }

      @override
      Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: const Text('Popup Settings'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              //*encloses the widget from which the relative positions will be 
              //*taken in a builder, in this case a button
              Builder(
                builder: (context) {
                  return RawMaterialButton(
                    fillColor: Colors.indigo,
                    constraints: const BoxConstraints(minWidth: 200),
                    onPressed: () => _showPopup(context),
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(8.0)
                    ),
                    padding: const EdgeInsets.symmetric(vertical: 10.0),
                    child: const Text('Show Menu', style: TextStyle(color: 
    Colors.white)),
                  );
                }
              ),
            ],
          ),
        ),
      );
    }
  }
Run Code Online (Sandbox Code Playgroud)


Aym*_*out 5

好吧,我无法通过该showMenu功能实现它,但是可以通过使用 aPopUpMenuButton并将其偏移量设置为底部应用栏的高度来实现。

这是一个示例代码:

PopupMenuButton<int>(
    offset: const Offset(0, -380),
    itemBuilder: (context) => [
      PopupMenuItem<int>(
          value: 0,
          child: PopUpMenuTile(
            isActive: true,
            icon: Icons.fiber_manual_record,
            title:'Stop recording',
          )),
      PopupMenuItem<int>(
          value: 1,
          child: PopUpMenuTile(
            isActive: true,
            icon: Icons.pause,
            title: 'Pause recording',
          )),
      PopupMenuItem<int>(
          value: 2,
          child: PopUpMenuTile(
            icon: Icons.group,
            title: 'Members',
          )),
      PopupMenuItem<int>(
          value: 3,
          child: PopUpMenuTile(
            icon: Icons.person_add,
            title: 'Invite members',
          )),
    ],
    child: Column(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        Icon(Icons.more_vert,
            color: Colors.white60),
        Text(translate('more'),
            style: Theme.of(context)
                .textTheme
                .caption)
      ],
    ),
  )
Run Code Online (Sandbox Code Playgroud)

自定义弹出菜单磁贴的代码如下,即使它与问题无关:

class PopUpMenuTile extends StatelessWidget {
  const PopUpMenuTile(
      {Key key,
      @required this.icon,
      @required this.title,
      this.isActive = false})
      : super(key: key);
  final IconData icon;
  final String title;
  final bool isActive;

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.max,
      mainAxisAlignment: MainAxisAlignment.start,
      children: <Widget>[
        Icon(icon,
            color: isActive
                ? Theme.of(context).accentColor
                : Theme.of(context).primaryColor),
        const SizedBox(
          width: 8,
        ),
        Text(
          title,
          style: Theme.of(context).textTheme.headline4.copyWith(
              color: isActive
                  ? Theme.of(context).accentColor
                  : Theme.of(context).primaryColor),
        ),
      ],
    );
  }
}
Run Code Online (Sandbox Code Playgroud)