Skip to content

PopupMenuButton's elevation is not being respected when using useMaterial3 #105101

@Mayb3Nots

Description

@Mayb3Nots

Steps to Reproduce

  1. Execute flutter run on the code sample
  2. Click on the PopupMenuButton.
  3. You will see a menu without elevation.

Expected results:

According to material3 specs for Menus we should be able to see elevation.
(Side note that #91605 doesnt state any progress of the migration of Menu while in the material site says it is in progress)
image

When running the sample code and not using the useMaterial3 flag it shows elevation as it should.
image

Actual results:

As you can see without elevation its very hard to notice the popup menu.
image

Code sample
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(),
      home: Scaffold(
          appBar: AppBar(
        actions: [
          PopupMenuButton(
            itemBuilder: (context) => List.generate(
                4, (index) => PopupMenuItem(child: Text('Item $index'))),
          )
        ],
      )),
    );
  }
}
Logs
[√] Flutter (Channel stable, 3.0.1, on Microsoft Windows [Version 10.0.22000.675], locale en-MY)
    • Flutter version 3.0.1 at C:\src\flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision fb57da5f94 (12 days ago), 2022-05-19 15:50:29 -0700
    • Engine revision caaafc5604
    • Dart version 2.17.1
    • DevTools version 2.12.2

[√] Android toolchain - develop for Android devices (Android SDK version 32.1.0-rc1)
    • Android SDK at C:\Users\samue\AppData\Local\Android\sdk
    • Platform android-32, build-tools 32.1.0-rc1
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 11.0.12+7-b1504.28-7817840)
    • All Android licenses accepted.

[√] Chrome - develop for the web
    • Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe

[X] Visual Studio - develop for Windows
    X Visual Studio not installed; this is necessary for Windows development.
      Download at https://visualstudio.microsoft.com/downloads/.
      Please install the "Desktop development with C++" workload, including all of its default components

[√] Android Studio (version 2021.2)
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin can be installed from:
       https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
       https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.12+7-b1504.28-7817840)

[√] VS Code (version 1.67.2)
    • VS Code at C:\Users\samue\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension version 3.40.0

[√] Connected device (4 available)
    • sdk gphone64 x86 64 (mobile) • emulator-5554 • android-x64    • Android 12 (API 31) (emulator)
    • Windows (desktop)            • windows       • windows-x64    • Microsoft Windows [Version 10.0.22000.675]
    • Chrome (web)                 • chrome        • web-javascript • Google Chrome 102.0.5005.62
    • Edge (web)                   • edge          • web-javascript • Microsoft Edge 101.0.1210.53

[√] HTTP Host Availability
    • All required HTTP hosts are available

Workaround

Since I rely on userMaterial3 for my app I cant disable it. But a workaround is to disable it only for the PopupMenuButton like this.

Theme(
            data: Theme.of(context).copyWith(useMaterial3: false),
            child: PopupMenuButton(
              itemBuilder: (context) => List.generate(
                  4, (index) => PopupMenuItem(child: Text('Item $index'))),
            ),
          )

or

specify the shadowColor in ThemeData. HOWEVER, this doesn't work if you already specify the colorScheme and no specifying the shadow property in ColorScheme doesnt fix the issue too. So if you use colorScheme in you app you have no choice but to use the solution above.

This code will still give the same issue

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
          useMaterial3: true,
          shadowColor: Colors.black,
          colorScheme: const ColorScheme.light(shadow: Colors.black)),
      home: Scaffold(
          appBar: AppBar(
        actions: [
          PopupMenuButton(
            itemBuilder: (context) => List.generate(
                4, (index) => PopupMenuItem(child: Text('Item $index'))),
          )
        ],
      )),
    );
  }
}

The real solution here would be to expose the shadowColor to the PopupMenuButton constructor so that we can specify it or give it a default value or follow the colorScheme's shadow property?

child: Material(
shape: route.shape ?? popupMenuTheme.shape,
color: route.color ?? popupMenuTheme.color,
type: MaterialType.card,
elevation: route.elevation ?? popupMenuTheme.elevation ?? 8.0,
child: Align(
alignment: AlignmentDirectional.topEnd,
widthFactor: width.evaluate(route.animation!),
heightFactor: height.evaluate(route.animation!),
child: child,

This is not really a bug per se because according to the doc this is the expected behavior of using the userMaterial3 flag. (See #102296 (comment)). However, as a side effect, we made the PopupMenuButton not follow the material spec.

I would love to contribute and fix this issue if this is actually an issue and my solution is more than sufficient or I just have overlooked a way to enable elevation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    r: duplicateIssue is closed as a duplicate of an existing issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions