Skip to content

SafeArea.maintainBottomViewPadding should be true by default #59204

Description

@Piinks

Found while investigating #58942

When Scaffold.resizeToAvoidBottomInsets: false, the layout will shift when the keyboard opens if there is a SafeArea in the Scaffold's body.

This is because in scaffold.dart:

// The minimum insets for contents of the Scaffold to keep visible.

    final EdgeInsets minInsets = mediaQuery.padding.copyWith(
      bottom: _resizeToAvoidBottomInset ? mediaQuery.viewInsets.bottom : 0.0,
    );

You can see in the gif below that the white safe space under the keyboard goes away when it opens.

ezgif com-video-to-gif

Reproduction

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        resizeToAvoidBottomInset: false,
        appBar: AppBar(title: Text('Demo')),
        body: SafeArea(
          child: 
          Container(
            color: Colors.yellow,
            child: Center(child: TextField())
          ),
        ),
        floatingActionButton: RaisedButton(
          onPressed: () {},
          child: Text('Button'),
        ),
      ),
    );
  }
}

flutter doctor

[✓] Flutter (Channel master, 1.19.0-6.0.pre.51, on Mac OS X 10.15.4 19E287, locale en-US)
    • Flutter version 1.19.0-6.0.pre.51 at /Users/katelovett/github/flutter
    • Framework revision 75fd73d818 (56 minutes ago), 2020-06-10 13:49:35 -0700
    • Engine revision e8c13aa012
    • Dart version 2.9.0 (build 2.9.0-14.0.dev 5c1376615e)

[✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    • Android SDK at /Users/katelovett/Library/Android/sdk
    • Platform android-28, build-tools 28.0.3
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 11.3.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 11.3.1, Build version 11C505
    • CocoaPods version 1.9.1

[✓] Android Studio (version 3.4)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 36.1.1
    • Dart plugin version 183.6270
    • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01)

[✓] VS Code (version 1.45.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.11.0

[✓] Connected device (1 available)
    • iPhone 11 Pro Max • A8FFA716-A67B-4468-B92B-F2B61F2306A0 • ios • com.apple.CoreSimulator.SimRuntime.iOS-13-3 (simulator)

Activity

  1. added
    frameworkflutter/packages/flutter repository. See also f: labels.
    p: material_uimaterial_ui package in flutter/packages
    a: qualityA truly polished experience
    on Jun 10, 2020
  2. added this to the 1.21 - July 2020 milestone on Jun 10, 2020
  3. self-assigned this
    on Jun 10, 2020
  4. Piinks commented on Jun 10, 2020

    @Piinks
    ContributorAuthor

    Well gosh I was just missing SafeArea.maintainBottomViewPadding: true. Which I added a year ago in #34298
    Hm.

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            resizeToAvoidBottomInset: false,
            appBar: AppBar(title: Text('Demo')),
            body: SafeArea(
              maintainBottomViewPadding: true,
              child: Container(
                color: Colors.yellow,
                child: Center(child: TextField())
              ),
            ),
            floatingActionButton: RaisedButton(
              onPressed: () {},
              child: Text('Button'),
            ),
          ),
        );
      }
    }
  5. Piinks commented on Jun 10, 2020

    @Piinks
    ContributorAuthor

    I think maybe SafeArea.maintainBottomViewPadding should be true by default. I am going to explore this some more.

  6. changed the title [-]Keyboard causes Scaffold+SafeArea to resize when resizeToAvoidBottomInsets=false[/-] [+]SafeArea.maintainBottomViewPadding should be true by default[/+] on Jun 10, 2020
  7. removed this from the 1.21 - July 2020 milestone on Jul 21, 2020
  8. removed their assignment
    on Jul 21, 2020
  9. added
    c: API breakBackwards-incompatible API changes
    a: layoutSystemChrome and Framework's Layout Issues
    and removed
    p: material_uimaterial_ui package in flutter/packages
    on Jul 21, 2020
  10. Piinks commented on Jul 21, 2020

    @Piinks
    ContributorAuthor

    I've looked at this a bit and it seems that this would have much larger implications than I originally thought.

    SafeArea.maintainViewPadding was added to incorporate the, also new, MediaQuery.viewPadding. Since MediaQuery.viewPadding is an ATF addition, it is not widely used throughout the framework. Often where a widget should use the viewPadding, it uses padding with special handling for edge cases that viewPadding would address, for example, the Scaffold accounts for maintaining the padding when arranging the various Scaffold elements :

    So while changing this may seem trivial, it would actual require large scale refactoring across the framework. For example, BottomNavigationBar would be broken in that, instead of the TextField shifting down in the example above, the BottomNavigationBar would shift up. A lot of care would need to be taken in this change to check every potentially affected widget.

    I think that viewPadding addressing the edge case it came in to fix (#29941) is ok for now. The true yak shave here would be re-factoring MediaQuery and all the affected widgets in one go to avoid breaking while achieving the desired default behavior in the example above, clearing up what is a bit of confusing API. I've added it to #24722 as a large breaking change that would improve the API surface.

    I won't be undertaking this currently, so I'm removing my assignment. I'll leave this open for discussion & future work.

  11. added
    c: proposalA detailed proposal for a change to Flutter
    and removed
    has reproducible stepsThe issue has been confirmed reproducible and is ready to work on
    on Jul 30, 2020
  12. added
    P3Issues that are less important to the Flutter project
    and removed on Jun 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Issues that are less important to the Flutter projecta: layoutSystemChrome and Framework's Layout Issuesa: qualityA truly polished experiencec: API breakBackwards-incompatible API changesc: new featureNothing broken; request for a new capabilityc: proposalA detailed proposal for a change to Flutterframeworkflutter/packages/flutter repository. See also f: labels.team-frameworkOwned by Framework teamtriaged-frameworkTriaged by Framework team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions