Repository navigation
Paint scaffold persistent bottom sheet background color behind the keyboard - #186365
victorsanni wants to merge 18 commits into
Conversation
|
An existing Git SHA, To re-trigger presubmits after closing or re-opeing a PR, or pushing a HEAD commit (i.e. with |
|
In the before/after image, the padding around the text field is gone. Is that intentional? |
Oops... thanks for catching that. I mistakenly used images from two different APIs in my repro app, one with padding and one without. Fixed. |
|
I've marked this PR as not ready to port to flutter/packages yet. |
|
This pull request contains changes to Material or Cupertino, which are currently frozen in this repository. Changes should be made in Please refer to #188444 for instructions. |
…a size-lying render object Replaces _RenderBottomSheetSurface, _BottomSheetContentClip, _BottomSheetClipper, _BottomSheetSemanticsClip, _BottomSheetContentMaterial and the adoption of a user-supplied BottomSheet with the approach from 70dac41: - _ScaffoldLayout lays the persistent bottom sheet's slot out to the bottom edge available to it (contentBottom + the keyboard inset not already covered by the bottom bars) and reports the content-only height to keep FAB and snackbar geometry unchanged. The inset travels to the pre-built sheets via _BottomSheetBoxConstraints + a LayoutBuilder, the same pattern as _BodyBoxConstraints / _BodyBuilder. - BottomSheet.bottomInset pads the content inside the sheet's Material, so the surface (color, tint, elevation, shape) continues behind the keyboard while _childHeight and `constraints` are measured against the content. The Padding is always present so the content's element tree and focus survive the inset changing. Because the sheet is laid out within its slot, no clipping is needed: a Scaffold shorter than the keyboard keeps the sheet inside its bounds. Tests move to scaffold_bottom_sheet_keyboard_test.dart (13 tests): extension with/without keyboard, resize opt-out, bottom navigation bar, docked FAB, focus preservation, fling and slow-drag dismissal thresholds, constraints, standalone bottomInset, taps in the extension, a Scaffold shorter than the keyboard, modal sheets unaffected, and a nested BottomSheet not being extended twice. Lifecycle hardening of removeCurrentBottomSheet and forwarding of a user-supplied BottomSheet's properties are left for separate changes.
No new test file: the Scaffold-level tests join the other persistent bottom sheet tests in persistent_bottom_sheet_test.dart (group 'keyboard inset'), and bottom_sheet_test.dart gains a 'BottomSheet.bottomInset' group that exercises the new API on a standalone BottomSheet: - extends the Material below the content (plus the default and the non-negative assert) - constraints bound the content, not the inset (minHeight and maxHeight) - drag-to-dismiss threshold is measured against the content, driven through a real AnimationController - changing bottomInset preserves the content state and focus - showModalBottomSheet does not set bottomInset
…omSheet.bottomInset _StandardBottomSheet now pads its content by the keyboard inset inside the BottomSheet's Material and grows the sheet's constraints by the same amount, so BottomSheet and its API are unchanged. The whole sheet now follows the finger while the keyboard is up. Before, drag progress was measured against the content alone while the reveal animated the full sheet, so the sheet ran ahead of the finger. A slow drag now closes the sheet past half of its full height, including the part behind the keyboard, like a modal sheet that pads its content by the keyboard height.
… behind the keyboard (#13242) Ports flutter/flutter#186365 to `material_ui` (design: https://flutter.dev/go/ios-26-keyboard-bleed). With a persistent bottom sheet (`Scaffold.bottomSheet` or `ScaffoldState.showBottomSheet`) and `resizeToAvoidBottomInset: true`, the sheet is lifted above the keyboard and the `Scaffold`'s own `Material` is what sits behind the keyboard. On iOS 26 the keyboard is translucent, so the scaffold color shows through under the sheet instead of the sheet's color. `_ScaffoldLayout` now extends the persistent sheet's slot by the part of the keyboard inset not already covered by the bottom bars, while still reporting the content-only height so FAB and `SnackBar` geometry are unchanged. `_StandardBottomSheet` pads its content inside the `BottomSheet`'s `Material` by that amount (growing the sheet's constraints to match), so the sheet's surface continues behind the keyboard. `resizeToAvoidBottomInset: false`, `showModalBottomSheet`, and `BottomSheet`'s public API are unchanged. Fixes the framework-owned part of flutter/flutter#179482. ## Before <img width="368" height="405" alt="before" src="https://github.com/user-attachments/assets/d60ec5b8-60e7-4ea5-881e-d1fe80fa2e4f" /> ## After <img width="368" height="405" alt="after" src="https://github.com/user-attachments/assets/0f8ae510-40bc-497f-b9a8-9545b5a42e43" /> ## Pre-Review Checklist [^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
Fixes the framework-owned part of #179482.
Problem
With a persistent bottom sheet (
Scaffold.bottomSheetorScaffoldState.showBottomSheet) andresizeToAvoidBottomInset: true, the sheet is lifted above the keyboard and theScaffold's ownMaterial(Scaffold.backgroundColor) is what sits behind the keyboard. On iOS 26 the keyboard is translucent, so the scaffold color shows through under the sheet instead of the sheet's color.Fix
Lay the sheet out all the way to the bottom and pad its content, instead of lying about its size:
_ScaffoldLayoutextends the persistent sheet's slot by the part of the keyboard inset that is not already covered by the bottom bars (bottomSheetKeyboardInset), and keeps reporting the content-only height so FAB andSnackBargeometry are unchanged. The inset reaches the pre-built sheet widgets through_BottomSheetBoxConstraints+ aLayoutBuilder, the same pattern as_BodyBoxConstraints/_BodyBuilder.BottomSheet.bottomInset(default0): aPaddinginside the sheet'sMaterial, so the surface (color, surface tint, elevation, shape) continues behind the keyboard while_childHeight, the drag/fling dismissal thresholds andconstraintsare still measured against the content. ThePaddingis always present so the content's element tree and focus survive the inset changing.Because the sheet is laid out within its slot, a
Scaffoldshorter than the keyboard keeps the sheet inside its bounds without any clipping.Behavior notes
Materialcolor extends (showBottomSheet(backgroundColor:),BottomSheetThemeData.backgroundColor, or the default surface color). A child'sContainer(color:)does not.Materialabsorbs taps below the content, which is what theScaffold'sMaterialdid there before. Only a docked keyboard produces an inset.resizeToAvoidBottomInset: false,showModalBottomSheet, and aBottomSheetpassed directly asScaffold.bottomSheetbehave as before.Tests
No new test file.
persistent_bottom_sheet_test.dartgains akeyboard insetgroup (11 tests): extension with and without a keyboard,resizeToAvoidBottomInset: false, bottom navigation bar, docked FAB, focus preserved while the keyboard appears, fling and slow-drag dismissal thresholds,constraints, taps in the extension, aScaffoldshorter than the keyboard, and a nestedBottomSheetnot being extended twice.bottom_sheet_test.dartgains aBottomSheet.bottomInsetgroup (5 tests) that exercises the new API on a standaloneBottomSheet: layout (plus the default value and the non-negative assert),constraints(min and max) bounding the content rather than the inset, the drag-to-dismiss threshold measured against the content through a realAnimationController, state and focus preserved across inset changes, andshowModalBottomSheetnot setting it.Pre-launch Checklist
///).