Skip to content

Scrolling closes menuAnchor widget #122168

@whiskeyPeak

Description

@whiskeyPeak
Screencast.from.2023-03-08.04-54-02.webm

Happens on both stable and master

flutter doctor:

[!] Flutter (Channel master, 3.9.0-1.0.pre.92, on Fedora Linux 37 (Workstation Edition) 6.1.11-200.fc37.x86_64, locale en_GB.UTF-8)
    • Flutter version 3.9.0-1.0.pre.92 on channel master at /home/henryr/Dev/Github/Flutter/flutter
    ! Upstream repository https://github.com/whiskeyPeak/flutter.git is not a standard remote.
      Set environment variable "FLUTTER_GIT_URL" to https://github.com/whiskeyPeak/flutter.git to dismiss this error.
    • Framework revision 5a279edc23 (3 hours ago), 2023-03-07 21:24:23 -0500
    • Engine revision 694a14ca6e
    • Dart version 3.0.0 (build 3.0.0-308.0.dev)
    • DevTools version 2.22.2
    • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks
      and upgrades.

[!] Android toolchain - develop for Android devices (Android SDK version 33.0.2)
    • Android SDK at /home/henryr/Android/Sdk
    • Platform android-33-ext4, build-tools 33.0.2
    • Java binary at: /home/henryr/Dev/SDK/Android Studio/android-studio/jbr/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.15+0-b2043.56-8887301)
    ! Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses

[✓] Chrome - develop for the web
    • Chrome at google-chrome

[✓] Linux toolchain - develop for Linux desktop
    • clang version 15.0.7 (Fedora 15.0.7-1.fc37)
    • cmake version 3.25.2
    • ninja version 1.10.2
    • pkg-config version 1.8.0

[✓] Android Studio (version 2022.1)
    • Android Studio at /home/henryr/Dev/SDK/Android Studio/android-studio
    • Flutter plugin version 72.0.2
    • Dart plugin version 221.6096
    • Java version OpenJDK Runtime Environment (build 11.0.15+0-b2043.56-8887301)

[✓] Connected device (2 available)
    • Linux (desktop) • linux  • linux-x64      • Fedora Linux 37 (Workstation Edition) 6.1.11-200.fc37.x86_64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 110.0.5481.100

[✓] Network resources
    • All expected network resources are available.


Repro code:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
          //colorScheme: const ColorScheme.dark(),
          ),
      home: const Directionality(
          textDirection: TextDirection.ltr,
          child: MyHomePage(title: 'Flutter Demo Home Page')),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(MediaQuery.of(context).size.height.toString()),
        centerTitle: true,
      ),
      body: const Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          Column(
            children: [
              ButtonAnchorExample(),
              Expanded(child: SizedBox()),
            ],
          ),
          Column(
            children: [
              Expanded(child: SizedBox()),
              ButtonAnchorExample(),
            ],
          ),
        ],
      ),
    );
  }
}

class ButtonAnchorExample extends StatelessWidget {
  const ButtonAnchorExample({super.key});

  @override
  Widget build(BuildContext context) {
    return MenuAnchor(
      style: const MenuStyle(
        //maximumSize: MaterialStateProperty.all(const Size(500, 200)),
        visualDensity: VisualDensity.compact,
        //alignment: AlignmentDirectional.topEnd
      ),
      // This offset is not correct when menu direction is reversed
      alignmentOffset: const Offset(0, 10),
      builder: (context, controller, child) {
        return FilledButton.tonal(
          onPressed: () {
            if (controller.isOpen) {
              controller.close();
            } else {
              controller.open();
            }
          },
          child: const Text('Show menu'),
        );
      },
      menuChildren: [
        MenuItemButton(
          leadingIcon: const Icon(Icons.people_alt_outlined),
          child: const Text('Item 1'),
          onPressed: () {},
        ),
        MenuItemButton(
          leadingIcon: const Icon(Icons.remove_red_eye_outlined),
          child: const Text('Item 2'),
          onPressed: () {},
        ),
        MenuItemButton(
          leadingIcon: const Icon(Icons.refresh),
          onPressed: () {},
          child: const Text('Item 3'),
        ),
        SubmenuButton(
          trailingIcon: const Icon(Icons.add),
          menuStyle: const MenuStyle(
            visualDensity: VisualDensity.compact,
          ),
          alignmentOffset: const Offset(8, 0),
          menuChildren: [
            MenuItemButton(
              leadingIcon: const Icon(Icons.people_alt_outlined),
              child: const Text('Item 1'),
              onPressed: () {},
            ),
            MenuItemButton(
              leadingIcon: const Icon(Icons.remove_red_eye_outlined),
              child: const Text('Item 2'),
              onPressed: () {},
            ),
            MenuItemButton(
              leadingIcon: const Icon(Icons.refresh),
              onPressed: () {},
              child: const Text('Item 3'),
            ),
          ],
          child: const Text("SubMenuButton"),
        ),
        SubmenuButton(
          menuStyle: const MenuStyle(
            visualDensity: VisualDensity.compact,
          ),
          alignmentOffset: const Offset(8, 0),
          menuChildren: [
            MenuItemButton(
              leadingIcon: const Icon(Icons.people_alt_outlined),
              child: const Text('Item 1'),
              onPressed: () {},
            ),
            MenuItemButton(
              leadingIcon: const Icon(Icons.remove_red_eye_outlined),
              child: const Text('Item 2'),
              onPressed: () {},
            ),
            MenuItemButton(
              leadingIcon: const Icon(Icons.refresh),
              onPressed: () {},
              child: const Text('Item 3'),
            ),
          ],
          child: const Text("SubMenuButton"),
        ),
        SubmenuButton(
          menuStyle: const MenuStyle(
            visualDensity: VisualDensity.compact,
          ),
          alignmentOffset: const Offset(8, 0),
          menuChildren: [
            MenuItemButton(
              leadingIcon: const Icon(Icons.people_alt_outlined),
              child: const Text('Item 1'),
              onPressed: () {},
            ),
            MenuItemButton(
              leadingIcon: const Icon(Icons.remove_red_eye_outlined),
              child: const Text('Item 2'),
              onPressed: () {},
            ),
            MenuItemButton(
              leadingIcon: const Icon(Icons.refresh),
              onPressed: () {},
              child: const Text('Item 3'),
            ),
          ],
          child: const Text("SubMenuButton"),
        ),
        SubmenuButton(
          menuStyle: const MenuStyle(
            visualDensity: VisualDensity.compact,
          ),
          alignmentOffset: const Offset(8, 0),
          menuChildren: [
            MenuItemButton(
              leadingIcon: const Icon(Icons.people_alt_outlined),
              child: const Text('Item 1'),
              onPressed: () {},
            ),
            MenuItemButton(
              leadingIcon: const Icon(Icons.remove_red_eye_outlined),
              child: const Text('Item 2'),
              onPressed: () {},
            ),
            MenuItemButton(
              leadingIcon: const Icon(Icons.refresh),
              onPressed: () {},
              child: const Text('Item 3'),
            ),
          ],
          child: const Text("SubMenuButton"),
        ),
        SubmenuButton(
          menuStyle: const MenuStyle(
            visualDensity: VisualDensity.compact,
          ),
          alignmentOffset: const Offset(8, 0),
          menuChildren: [
            MenuItemButton(
              leadingIcon: const Icon(Icons.people_alt_outlined),
              child: const Text('Item 1'),
              onPressed: () {},
            ),
            MenuItemButton(
              leadingIcon: const Icon(Icons.remove_red_eye_outlined),
              child: const Text('Item 2'),
              onPressed: () {},
            ),
            MenuItemButton(
              leadingIcon: const Icon(Icons.refresh),
              onPressed: () {},
              child: const Text('Item 3'),
            ),
          ],
          child: const Text("SubMenuButton"),
        ),
        SubmenuButton(
          menuStyle: const MenuStyle(
            visualDensity: VisualDensity.compact,
          ),
          alignmentOffset: const Offset(8, 0),
          menuChildren: [
            SubmenuButton(
              menuStyle: const MenuStyle(
                visualDensity: VisualDensity.compact,
              ),
              alignmentOffset: const Offset(8, 0),
              menuChildren: [
                MenuItemButton(
                  leadingIcon: const Icon(Icons.people_alt_outlined),
                  child: const Text('Item 1'),
                  onPressed: () {},
                ),
                MenuItemButton(
                  leadingIcon: const Icon(Icons.remove_red_eye_outlined),
                  child: const Text('Item 2'),
                  onPressed: () {},
                ),
                MenuItemButton(
                  leadingIcon: const Icon(Icons.refresh),
                  onPressed: () {},
                  child: const Text('Item 3'),
                ),
              ],
              child: const Text("SubMenuButton"),
            ),
            SubmenuButton(
              menuStyle: const MenuStyle(
                visualDensity: VisualDensity.compact,
              ),
              alignmentOffset: const Offset(8, 0),
              menuChildren: [
                MenuItemButton(
                  leadingIcon: const Icon(Icons.people_alt_outlined),
                  child: const Text('Item 1'),
                  onPressed: () {},
                ),
                MenuItemButton(
                  leadingIcon: const Icon(Icons.remove_red_eye_outlined),
                  child: const Text('Item 2'),
                  onPressed: () {},
                ),
                MenuItemButton(
                  leadingIcon: const Icon(Icons.refresh),
                  onPressed: () {},
                  child: const Text('Item 3'),
                ),
              ],
              child: const Text("SubMenuButton"),
            ),
            SubmenuButton(
              menuStyle: const MenuStyle(
                visualDensity: VisualDensity.compact,
              ),
              alignmentOffset: const Offset(8, 0),
              menuChildren: [
                MenuItemButton(
                  leadingIcon: const Icon(Icons.people_alt_outlined),
                  child: const Text('Item 1'),
                  onPressed: () {},
                ),
                MenuItemButton(
                  leadingIcon: const Icon(Icons.remove_red_eye_outlined),
                  child: const Text('Item 2'),
                  onPressed: () {},
                ),
                MenuItemButton(
                  leadingIcon: const Icon(Icons.refresh),
                  onPressed: () {},
                  child: const Text('Item 3'),
                ),
              ],
              child: const Text("SubMenuButton"),
            ),
            SubmenuButton(
              menuStyle: const MenuStyle(
                visualDensity: VisualDensity.compact,
              ),
              alignmentOffset: const Offset(8, 0),
              menuChildren: [
                MenuItemButton(
                  leadingIcon: const Icon(Icons.people_alt_outlined),
                  child: const Text('Item 1'),
                  onPressed: () {},
                ),
                MenuItemButton(
                  leadingIcon: const Icon(Icons.remove_red_eye_outlined),
                  child: const Text('Item 2'),
                  onPressed: () {},
                ),
                MenuItemButton(
                  leadingIcon: const Icon(Icons.refresh),
                  onPressed: () {},
                  child: const Text('Item 3'),
                ),
              ],
              child: const Text("SubMenuButton"),
            ),
            SubmenuButton(
              menuStyle: const MenuStyle(
                visualDensity: VisualDensity.compact,
              ),
              alignmentOffset: const Offset(8, 0),
              menuChildren: [
                MenuItemButton(
                  leadingIcon: const Icon(Icons.people_alt_outlined),
                  child: const Text('Item 1'),
                  onPressed: () {},
                ),
                MenuItemButton(
                  leadingIcon: const Icon(Icons.remove_red_eye_outlined),
                  child: const Text('Item 2'),
                  onPressed: () {},
                ),
                SubmenuButton(
                  menuStyle: const MenuStyle(
                    visualDensity: VisualDensity.compact,
                  ),
                  alignmentOffset: const Offset(8, 0),
                  menuChildren: [
                    MenuItemButton(
                      leadingIcon: const Icon(Icons.people_alt_outlined),
                      child: const Text('Item 1'),
                      onPressed: () {},
                    ),
                    MenuItemButton(
                      leadingIcon: const Icon(Icons.remove_red_eye_outlined),
                      child: const Text('Item 2'),
                      onPressed: () {},
                    ),
                    MenuItemButton(
                      leadingIcon: const Icon(Icons.refresh),
                      onPressed: () {},
                      child: const Text('Item 3'),
                    ),
                  ],
                  child: const Text("SubMenuButton"),
                ),
                SubmenuButton(
                  menuStyle: const MenuStyle(
                    visualDensity: VisualDensity.compact,
                  ),
                  alignmentOffset: const Offset(8, 0),
                  menuChildren: [
                    MenuItemButton(
                      leadingIcon: const Icon(Icons.people_alt_outlined),
                      child: const Text('Item 1'),
                      onPressed: () {},
                    ),
                    MenuItemButton(
                      leadingIcon: const Icon(Icons.remove_red_eye_outlined),
                      child: const Text('Item 2'),
                      onPressed: () {},
                    ),
                    MenuItemButton(
                      leadingIcon: const Icon(Icons.refresh),
                      onPressed: () {},
                      child: const Text('Item 3'),
                    ),
                  ],
                  child: const Text("SubMenuButton"),
                ),
                SubmenuButton(
                  menuStyle: const MenuStyle(
                    visualDensity: VisualDensity.compact,
                  ),
                  alignmentOffset: const Offset(8, 0),
                  menuChildren: [
                    MenuItemButton(
                      leadingIcon: const Icon(Icons.people_alt_outlined),
                      child: const Text('Item 1'),
                      onPressed: () {},
                    ),
                    MenuItemButton(
                      leadingIcon: const Icon(Icons.remove_red_eye_outlined),
                      child: const Text('Item 2'),
                      onPressed: () {},
                    ),
                    MenuItemButton(
                      leadingIcon: const Icon(Icons.refresh),
                      onPressed: () {},
                      child: const Text('Item 3'),
                    ),
                  ],
                  child: const Text("SubMenuButton"),
                ),
                SubmenuButton(
                  menuStyle: const MenuStyle(
                    visualDensity: VisualDensity.compact,
                  ),
                  alignmentOffset: const Offset(8, 0),
                  menuChildren: [
                    MenuItemButton(
                      leadingIcon: const Icon(Icons.people_alt_outlined),
                      child: const Text('Item 1'),
                      onPressed: () {},
                    ),
                    SubmenuButton(
                      menuStyle: const MenuStyle(
                        visualDensity: VisualDensity.compact,
                      ),
                      alignmentOffset: const Offset(8, 0),
                      menuChildren: [
                        MenuItemButton(
                          leadingIcon: const Icon(Icons.people_alt_outlined),
                          child: const Text('Item 1'),
                          onPressed: () {},
                        ),
                        MenuItemButton(
                          leadingIcon:
                              const Icon(Icons.remove_red_eye_outlined),
                          child: const Text('Item 2'),
                          onPressed: () {},
                        ),
                        MenuItemButton(
                          leadingIcon: const Icon(Icons.refresh),
                          onPressed: () {},
                          child: const Text('Item 3'),
                        ),
                      ],
                      child: const Text("SubMenuButton"),
                    ),
                    SubmenuButton(
                      menuStyle: const MenuStyle(
                        visualDensity: VisualDensity.compact,
                      ),
                      alignmentOffset: const Offset(8, 0),
                      menuChildren: [
                        MenuItemButton(
                          leadingIcon: const Icon(Icons.people_alt_outlined),
                          child: const Text('Item 1'),
                          onPressed: () {},
                        ),
                        MenuItemButton(
                          leadingIcon:
                              const Icon(Icons.remove_red_eye_outlined),
                          child: const Text('Item 2'),
                          onPressed: () {},
                        ),
                        MenuItemButton(
                          leadingIcon: const Icon(Icons.refresh),
                          onPressed: () {},
                          child: const Text('Item 3'),
                        ),
                      ],
                      child: const Text("SubMenuButton"),
                    ),
                    MenuItemButton(
                      leadingIcon: const Icon(Icons.remove_red_eye_outlined),
                      child: const Text('Item 2'),
                      onPressed: () {},
                    ),
                    MenuItemButton(
                      leadingIcon: const Icon(Icons.refresh),
                      onPressed: () {},
                      child: const Text('Item 3'),
                    ),
                  ],
                  child: const Text("SubMenuButton"),
                ),
                MenuItemButton(
                  leadingIcon: const Icon(Icons.refresh),
                  onPressed: () {},
                  child: const Text('Item 3'),
                ),
              ],
              child: const Text("SubMenuButton"),
            ),
            MenuItemButton(
              leadingIcon: const Icon(Icons.people_alt_outlined),
              child: const Text('Item 1'),
              onPressed: () {},
            ),
            MenuItemButton(
              leadingIcon: const Icon(Icons.remove_red_eye_outlined),
              child: const Text('Item 2'),
              onPressed: () {},
            ),
            MenuItemButton(
              leadingIcon: const Icon(Icons.refresh),
              onPressed: () {},
              child: const Text('Item 3'),
            ),
          ],
          child: const Text("SubMenuButton"),
        ),
        SubmenuButton(
          menuStyle: const MenuStyle(
            visualDensity: VisualDensity.compact,
          ),
          alignmentOffset: const Offset(8, 0),
          menuChildren: [
            MenuItemButton(
              leadingIcon: const Icon(Icons.people_alt_outlined),
              child: const Text('Item 1'),
              onPressed: () {},
            ),
            MenuItemButton(
              leadingIcon: const Icon(Icons.remove_red_eye_outlined),
              child: const Text('Item 2'),
              onPressed: () {},
            ),
            MenuItemButton(
              leadingIcon: const Icon(Icons.refresh),
              onPressed: () {},
              child: const Text('Item 3'),
            ),
          ],
          child: const Text("SubMenuButton"),
        ),
        SubmenuButton(
          menuStyle: const MenuStyle(
            visualDensity: VisualDensity.compact,
          ),
          alignmentOffset: const Offset(8, 0),
          menuChildren: [
            MenuItemButton(
              leadingIcon: const Icon(Icons.people_alt_outlined),
              child: const Text('Item 1'),
              onPressed: () {},
            ),
            MenuItemButton(
              leadingIcon: const Icon(Icons.remove_red_eye_outlined),
              child: const Text('Item 2'),
              onPressed: () {},
            ),
            MenuItemButton(
              leadingIcon: const Icon(Icons.refresh),
              onPressed: () {},
              child: const Text('Item 3'),
            ),
            SubmenuButton(
              menuStyle: const MenuStyle(
                visualDensity: VisualDensity.compact,
              ),
              alignmentOffset: const Offset(8, 0),
              menuChildren: [
                MenuItemButton(
                  leadingIcon: const Icon(Icons.people_alt_outlined),
                  child: const Text('Item 1'),
                  onPressed: () {},
                ),
                MenuItemButton(
                  leadingIcon: const Icon(Icons.remove_red_eye_outlined),
                  child: const Text('Item 2'),
                  onPressed: () {},
                ),
                MenuItemButton(
                  leadingIcon: const Icon(Icons.refresh),
                  onPressed: () {},
                  child: const Text('Item 3'),
                ),
              ],
              child: const Text("SubMenuButton"),
            ),
            SubmenuButton(
              menuStyle: const MenuStyle(
                visualDensity: VisualDensity.compact,
              ),
              alignmentOffset: const Offset(8, 0),
              menuChildren: [
                MenuItemButton(
                  leadingIcon: const Icon(Icons.people_alt_outlined),
                  child: const Text('Item 1'),
                  onPressed: () {},
                ),
                MenuItemButton(
                  leadingIcon: const Icon(Icons.remove_red_eye_outlined),
                  child: const Text('Item 2'),
                  onPressed: () {},
                ),
                MenuItemButton(
                  leadingIcon: const Icon(Icons.refresh),
                  onPressed: () {},
                  child: const Text('Item 3'),
                ),
              ],
              child: const Text("SubMenuButton"),
            ),
            SubmenuButton(
              menuStyle: const MenuStyle(
                visualDensity: VisualDensity.compact,
              ),
              alignmentOffset: const Offset(8, 0),
              menuChildren: [
                MenuItemButton(
                  leadingIcon: const Icon(Icons.people_alt_outlined),
                  child: const Text('Item 1'),
                  onPressed: () {},
                ),
                MenuItemButton(
                  leadingIcon: const Icon(Icons.remove_red_eye_outlined),
                  child: const Text('Item 2'),
                  onPressed: () {},
                ),
                MenuItemButton(
                  leadingIcon: const Icon(Icons.refresh),
                  onPressed: () {},
                  child: const Text('Item 3'),
                ),
              ],
              child: const Text("SubMenuButton"),
            ),
          ],
          child: const Text("SubMenuButton"),
        ),
        SubmenuButton(
          menuStyle: const MenuStyle(
            visualDensity: VisualDensity.compact,
          ),
          alignmentOffset: const Offset(8, 0),
          menuChildren: [
            MenuItemButton(
              leadingIcon: const Icon(Icons.people_alt_outlined),
              child: const Text('Item 1'),
              onPressed: () {},
            ),
            MenuItemButton(
              leadingIcon: const Icon(Icons.remove_red_eye_outlined),
              child: const Text('Item 2'),
              onPressed: () {},
            ),
            MenuItemButton(
              leadingIcon: const Icon(Icons.refresh),
              onPressed: () {},
              child: const Text('Item 3'),
            ),
          ],
          child: const Text("SubMenuButton"),
        ),
      ],
    );
  }
}


Metadata

Metadata

Assignees

Labels

f: material designflutter/packages/flutter/material repository.f: scrollingViewports, list views, slivers, etc.found in release: 3.7Found to occur in 3.7found in release: 3.9Found to occur in 3.9frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer version

Type

No type

Projects

Status

Done (PR merged)

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions