mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Add header and footer support to NavigationDrawer (#168005)
<!-- Thanks for filing a pull request! Reviewers are typically assigned within a week of filing a request. To learn more about code review, see our documentation on Tree Hygiene: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md --> ## Description This PR attempts to add header and footer for `NavigationDrawer` widget as shown below:  ## Issues are fixed by this PR - #127621 - #135750 (partially) ## 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. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
parent
df29894372
commit
f182421dd2
@ -57,6 +57,8 @@ class NavigationDrawer extends StatelessWidget {
|
||||
const NavigationDrawer({
|
||||
super.key,
|
||||
required this.children,
|
||||
this.header,
|
||||
this.footer,
|
||||
this.backgroundColor,
|
||||
this.shadowColor,
|
||||
this.surfaceTintColor,
|
||||
@ -120,6 +122,16 @@ class NavigationDrawer extends StatelessWidget {
|
||||
/// widgets like headlines and dividers.
|
||||
final List<Widget> children;
|
||||
|
||||
/// A widget to display at the top of the layout.
|
||||
///
|
||||
/// Typically used for titles, navigation bars, or other header content.
|
||||
final Widget? header;
|
||||
|
||||
/// A widget to display at the bottom of the layout.
|
||||
///
|
||||
/// Typically used for actions, navigation controls, or other footer content.
|
||||
final Widget? footer;
|
||||
|
||||
/// The index into destinations for the current selected
|
||||
/// [NavigationDrawerDestination] or null if no destination is selected.
|
||||
///
|
||||
@ -173,7 +185,16 @@ class NavigationDrawer extends StatelessWidget {
|
||||
shadowColor: shadowColor ?? navigationDrawerTheme.shadowColor,
|
||||
surfaceTintColor: surfaceTintColor ?? navigationDrawerTheme.surfaceTintColor,
|
||||
elevation: elevation ?? navigationDrawerTheme.elevation,
|
||||
child: SafeArea(bottom: false, child: ListView(children: wrappedChildren)),
|
||||
child: SafeArea(
|
||||
bottom: false,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
if (header != null) header!,
|
||||
Expanded(child: ListView(children: wrappedChildren)),
|
||||
if (footer != null) footer!,
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -488,6 +488,46 @@ void main() {
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('NavigationDrawer can display header and footer', (WidgetTester tester) async {
|
||||
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
widgetSetup(tester, 3000, viewHeight: 3000);
|
||||
final Widget widget = _buildWidget(
|
||||
scaffoldKey,
|
||||
NavigationDrawer(
|
||||
header: const DrawerHeader(
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
spacing: 8,
|
||||
children: <Widget>[FlutterLogo(), Text('Header')],
|
||||
),
|
||||
),
|
||||
),
|
||||
footer: ListTile(
|
||||
leading: const FlutterLogo(),
|
||||
title: const Text('Footer'),
|
||||
trailing: const Icon(Icons.settings),
|
||||
onTap: () {},
|
||||
),
|
||||
children: <Widget>[
|
||||
for (int i = 0; i < 10; i++)
|
||||
NavigationDrawerDestination(icon: const Icon(Icons.home), label: Text('Item $i')),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(widget);
|
||||
scaffoldKey.currentState!.openDrawer();
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
|
||||
expect(find.byType(DrawerHeader), findsOneWidget);
|
||||
expect(find.text('Header'), findsOneWidget);
|
||||
expect(find.byType(FlutterLogo), findsNWidgets(2));
|
||||
expect(find.byType(ListTile), findsOneWidget);
|
||||
expect(find.text('Footer'), findsOneWidget);
|
||||
expect(find.byIcon(Icons.settings), findsOneWidget);
|
||||
});
|
||||
}
|
||||
|
||||
Widget _buildWidget(GlobalKey<ScaffoldState> scaffoldKey, Widget child, {bool? useMaterial3}) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user