Skip to content

Add support for full screen dialogs  #104961

Closed

Description

@guidezpl

Activity

  1. added
    c: new featureNothing broken; request for a new capability
    frameworkflutter/packages/flutter repository. See also f: labels.
    p: material_uimaterial_ui package in flutter/packages
    on May 30, 2022
  2. moved this to 🗺 Planned in Material 3on May 30, 2022
  3. HansMuller commented on Jun 2, 2022

    @HansMuller
    Contributor

    Part of #91605

  4. TahaTesser commented on Jun 16, 2022

    @TahaTesser
    Contributor

    This is required for #106101, looking at what is needed to make this feature possible.

  5. self-assigned this
    on Jun 17, 2022
  6. TahaTesser commented on Jul 13, 2022

    @TahaTesser
    Contributor

    cc: @guidezpl @darrenaustin

    Do you think creating a new FullscreenDialog widget is the way to go to make it work out of the box? or perhaps adding something like Dialog.fullscreen().

    We can create a fullscreen dialog using Dialog widget with some zero insetPadding and a Scaffold. If this is sufficient, we can close this issue.

    Code Sample
    import 'package:flutter/material.dart';
    
    void main() => runApp(const MyApp());
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key, this.dark = true, this.useMaterial3 = true});
    
      final bool dark;
      final bool useMaterial3;
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          themeMode: dark ? ThemeMode.dark : ThemeMode.light,
          theme: ThemeData(
            useMaterial3: useMaterial3,
            brightness: Brightness.light,
            colorSchemeSeed: const Color(0xff6750a4),
          ),
          darkTheme: ThemeData(
            useMaterial3: useMaterial3,
            brightness: Brightness.dark,
            colorSchemeSeed: const Color(0xff6750a4),
          ),
          home: const DialogExample(),
        );
      }
    }
    
    class DialogExample extends StatelessWidget {
      const DialogExample({super.key});
    
      Future<void> _dialog(BuildContext context) async {
        return showDialog(
          context: context,
          builder: (BuildContext context) {
            return Dialog(
              insetPadding: EdgeInsets.zero,
              child: Scaffold(
                appBar: AppBar(
                  title: const Text('Full-screen dialog title'),
                  centerTitle: false,
                  automaticallyImplyLeading: false,
                  leading: IconButton(
                    onPressed: () => Navigator.of(context).pop(),
                    icon: const Icon(Icons.close),
                  ),
                  actions: <Widget>[
                    TextButton(
                      onPressed: () => Navigator.of(context).pop(),
                      child: const Text('Save'),
                    ),
                  ],
                ),
              ),
            );
          },
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Dialog'),
          ),
          body: Center(
            child: ElevatedButton(
              onPressed: () => _dialog(context),
              child: const Text('Open Full-screen Dialog'),
            ),
          ),
        );
      }
    }
    
    Screen.Recording.2022-07-13.at.13.49.40.mov
  7. guidezpl commented on Jul 13, 2022

    @guidezpl
    MemberAuthor

    It does look very close, but not quite up to spec (save button padding). I do like Dialog.fullscreen() for this kind of case.

    Can you add some content to the example? I'd like to see how close to spec we are by default.

  8. TahaTesser commented on Jul 14, 2022

    @TahaTesser
    Contributor

    It's getting there but you're right, it's not quite up to spec, given the fullscreen_dialog specs and tokens. Now I think matching the specs is the way perhaps with Dialog.fullscreen()

    Code Sample
    import 'package:flutter/material.dart';
    
    import 'package:flutter/material.dart';
    
    void main() => runApp(const MyApp());
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key, this.dark = true, this.useMaterial3 = true});
    
      final bool dark;
      final bool useMaterial3;
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          themeMode: dark ? ThemeMode.dark : ThemeMode.light,
          theme: ThemeData(
            useMaterial3: useMaterial3,
            brightness: Brightness.light,
            colorSchemeSeed: const Color(0xff6750a4),
          ),
          darkTheme: ThemeData(
            useMaterial3: useMaterial3,
            brightness: Brightness.dark,
            colorSchemeSeed: const Color(0xff6750a4),
          ),
          home: const Example(),
        );
      }
    }
    
    class Example extends StatefulWidget {
      const Example({super.key});
    
      @override
      State<Example> createState() => _ExampleState();
    }
    
    class _ExampleState extends State<Example> {
      late TextEditingController _controller;
    
      @override
      void initState() {
        super.initState();
        _controller = TextEditingController(text: 'Flutter is amazing!');
      }
    
      @override
      void dispose() {
        _controller.dispose();
        super.dispose();
      }
    
      Future<void> _dialog(BuildContext context) async {
        return showDialog(
          context: context,
          builder: (BuildContext context) {
            return Dialog(
              insetPadding: EdgeInsets.zero,
              child: Scaffold(
                appBar: AppBar(
                  title: const Text('Full-screen dialog title'),
                  centerTitle: false,
                  automaticallyImplyLeading: false,
                  leading: IconButton(
                    onPressed: () => Navigator.of(context).pop(),
                    icon: const Icon(Icons.close),
                  ),
                  actions: <Widget>[
                    TextButton(
                      onPressed: () => Navigator.of(context).pop(),
                      child: const Text('Save'),
                    ),
                  ],
                ),
                body: Padding(
                  padding: const EdgeInsets.all(16.0),
                  child: Column(
                    children: <Widget>[
                      TextField(
                        controller: _controller,
                        decoration: const InputDecoration(
                            border: OutlineInputBorder(),
                            suffixIcon: Icon(Icons.arrow_drop_down)),
                      ),
                      const SizedBox(height: 20),
                      TextField(
                        controller: _controller,
                        decoration: const InputDecoration(
                          border: OutlineInputBorder(),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            );
          },
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text('Dialog'),
          ),
          body: Center(
            child: ElevatedButton(
              onPressed: () => _dialog(context),
              child: const Text('Open Full-screen Dialog'),
            ),
          ),
        );
      }
    }
    
    Preview
  9. TahaTesser commented on Jul 14, 2022

    @TahaTesser
    Contributor

    Dialog is actually an unopinionated dialog.

    In the Flutter context, AlertDialog is the dialog that provides the ability title, message, and actions buttons and the M3 Fullscreen dialog is similar to that but of course fullscreen.

    Also, AlertDialog has quite many parameters that are not related to Fullscreen Dialog

    In this case, creating a new FullscreenDialog makes more sense to me (Dialog being unopinionated means it has none of the features to support M3 tokens)

    Previously I migrated AlertDialog to M3 with tokens.

    Screenshot 2022-07-14 at 16 11 28

  10. guidezpl commented on Jul 14, 2022

    @guidezpl
    MemberAuthor

    Agreed that AlertDialog isn't the way to go for this. Since Dialog

    In this case, creating a new FullscreenDialog makes more sense to me (Dialog being unopinionated means it has none of the features to support M3 tokens)

    I'm not sure I understand this. Since Dialog is so close, wouldn't it make more sense to migrate it? We could have Dialog.fullscreen which sets insetPadding and a new padding or contentPadding to match spec, leaving the rest up to users.

    Also, if you overlay the sample with the spec, is the padding around the button the only padding difference?

  11. TahaTesser commented on Jul 15, 2022

    @TahaTesser
    Contributor

    I'm not sure I understand this. Since Dialog is so close, wouldn't it make more sense to migrate it? We could have Dialog.fullscreen which sets insetPadding and a new padding or contentPadding to match spec, leaving the rest up to users.

    That's what I thought at first, given Android doesn't provide a concrete fullscreen implementation.

    According to Dialogs - Full-screen dialogs and tokens, there needs to be a header with the title with app bar like height, the closing icon, and action text button and it should also elevate on the scroll and a divider.

    AlertDialog follows its specs so should fullscreen dialog given the similar tokens and specs above?

    Could we leave all this full-screen dialog design for the users to match the specs?

    I think the new FullscreenDialog that matches specs and uses the tokens to style header, icon, action button, and the divider is probably good? or I can create Dialog.fullscreen, and let the user create their header and divider using the AppBar widget?

  12. guidezpl commented on Jul 15, 2022

    @guidezpl
    MemberAuthor

    Both options are valid, but I suspect the customizeability of full screen dialogs is more important than providing an exact match to spec. I'd lean towards the Dialog.fullscreen approach.

  13. 1 remaining item

  14. pedromassango commented on Aug 22, 2022

    @pedromassango
    Member

    I was about to file a new issue for this :) Is someone working on this up?

  15. TahaTesser commented on Aug 22, 2022

    @TahaTesser
    Contributor

    @pedromassango
    I have the code ready to be filed. (I was on vacation and working on higher priority issues).

  16. TahaTesser commented on Aug 22, 2022

    @TahaTesser
    Contributor

    @pedromassango
    I have implemented Dialog.fullscreen based on the discussion. I will file the PR soon and would like it if you could take a look.

  17. pedromassango commented on Aug 22, 2022

    @pedromassango
    Member

    That is great 🏅

  18. TahaTesser commented on Sep 22, 2022

    @TahaTesser
    Contributor

    Update:
    Didn't forget about this. I was focused on getting some existing PRs merged.
    Filing this dialog tomorrow.

  19. moved this from To do to In progress in Nevercodeon Sep 22, 2022
  20. moved this from 🗺 Planned to 🚧 In Progress in Material 3on Sep 22, 2022
  21. moved this from In progress to PR submitted in Nevercodeon Sep 23, 2022
  22. Repository owner moved this from 🚧 In Progress to ✅ Done in Material 3on Sep 29, 2022
  23. Repository owner moved this from PR submitted to Done (PR merged) in Nevercodeon Sep 29, 2022
  24. github-actions commented on Oct 13, 2022

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  25. locked as resolved and limited conversation to collaborators on Oct 13, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

c: new featureNothing broken; request for a new capabilityframeworkflutter/packages/flutter repository. See also f: labels.p: material_uimaterial_ui package in flutter/packages

Type

No type

Projects

  • Status
    Done (PR merged)

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions