Feat: Add persistentFooterDecoration for scaffold (#167524)

Feat: Add persistentFooterDecoration for scaffold
fixes: #166478 

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

---------

Co-authored-by: Tong Mu <dkwingsmt@users.noreply.github.com>
This commit is contained in:
Kishan Rathore 2025-05-21 23:40:00 +05:30 committed by GitHub
parent f7354da75b
commit 33cdd8ef31
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 42 additions and 3 deletions

View File

@ -1697,6 +1697,7 @@ class Scaffold extends StatefulWidget {
this.floatingActionButtonAnimator,
this.persistentFooterButtons,
this.persistentFooterAlignment = AlignmentDirectional.centerEnd,
this.persistentFooterDecoration,
this.drawer,
this.onDrawerChanged,
this.endDrawer,
@ -1814,6 +1815,17 @@ class Scaffold extends StatefulWidget {
/// Defaults to [AlignmentDirectional.centerEnd].
final AlignmentDirectional persistentFooterAlignment;
/// Decoration for the container that holds the [persistentFooterButtons].
///
/// By default, this container has a top border with a width of 1.0, created by
/// [Divider.createBorderSide].
///
/// See also:
///
/// * [persistentFooterButtons], which defines the buttons to show in the footer.
/// * [persistentFooterAlignment], which defines the alignment of the footer buttons.
final BoxDecoration? persistentFooterDecoration;
/// A panel displayed to the side of the [body], often hidden on mobile
/// devices. Swipes in from either left-to-right ([TextDirection.ltr]) or
/// right-to-left ([TextDirection.rtl])
@ -3058,9 +3070,9 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
_addIfNonNull(
children,
Container(
decoration: BoxDecoration(
border: Border(top: Divider.createBorderSide(context, width: 1.0)),
),
decoration:
widget.persistentFooterDecoration ??
BoxDecoration(border: Border(top: Divider.createBorderSide(context, width: 1.0))),
child: SafeArea(
top: false,
child: IntrinsicHeight(

View File

@ -823,6 +823,33 @@ void main() {
expect(initialPoint, finalPoint);
});
testWidgets('Persistent bottom buttons can apply decoration', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: MediaQuery(
data: const MediaQueryData(padding: EdgeInsets.fromLTRB(10.0, 20.0, 30.0, 40.0)),
child: Scaffold(
body: SingleChildScrollView(
child: Container(color: Colors.amber[500], height: 5000.0, child: const Text('body')),
),
persistentFooterDecoration: const BoxDecoration(
border: Border(top: BorderSide(color: Colors.red)),
),
persistentFooterButtons: const <Widget>[Placeholder()],
),
),
),
);
final Finder persistentFooter =
find.ancestor(of: find.byType(OverflowBar), matching: find.byType(Container)).first;
final Decoration decoration = tester.widget<Container>(persistentFooter).decoration!;
expect(decoration, isA<BoxDecoration>());
expect((decoration as BoxDecoration).border!.top.color, Colors.red);
});
group('back arrow', () {
Future<void> expectBackIcon(WidgetTester tester, IconData expectedIcon) async {
final GlobalKey rootKey = GlobalKey();