1// Copyright 2014 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5/// @docImport 'drawer.dart';
6/// @docImport 'material.dart';
7/// @docImport 'user_accounts_drawer_header.dart';
8library;
9
10import 'package:flutter/widgets.dart';
11
12import 'debug.dart';
13import 'divider.dart';
14import 'theme.dart';
15
16const double _kDrawerHeaderHeight = 160.0 + 1.0; // bottom edge
17
18/// The top-most region of a Material Design drawer. The header's [child]
19/// widget, if any, is placed inside a [Container] whose [decoration] can be
20/// passed as an argument, inset by the given [padding].
21///
22/// Part of the Material Design [Drawer].
23///
24/// Requires one of its ancestors to be a [Material] widget. This condition is
25/// satisfied by putting the [DrawerHeader] in a [Drawer].
26///
27/// See also:
28///
29/// * [UserAccountsDrawerHeader], a variant of [DrawerHeader] that is
30/// specialized for showing user accounts.
31/// * <https://material.io/design/components/navigation-drawer.html>
32class DrawerHeader extends StatelessWidget {
33 /// Creates a Material Design drawer header.
34 ///
35 /// Requires one of its ancestors to be a [Material] widget.
36 const DrawerHeader({
37 super.key,
38 this.decoration,
39 this.margin = const EdgeInsets.only(bottom: 8.0),
40 this.padding = const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 8.0),
41 this.duration = const Duration(milliseconds: 250),
42 this.curve = Curves.fastOutSlowIn,
43 required this.child,
44 });
45
46 /// Decoration for the main drawer header [Container]; useful for applying
47 /// backgrounds.
48 ///
49 /// This decoration will extend under the system status bar.
50 ///
51 /// If this is changed, it will be animated according to [duration] and [curve].
52 final Decoration? decoration;
53
54 /// The padding by which to inset [child].
55 ///
56 /// The [DrawerHeader] additionally offsets the child by the height of the
57 /// system status bar.
58 ///
59 /// If the child is null, the padding has no effect.
60 final EdgeInsetsGeometry padding;
61
62 /// The margin around the drawer header.
63 final EdgeInsetsGeometry? margin;
64
65 /// The duration for animations of the [decoration].
66 final Duration duration;
67
68 /// The curve for animations of the [decoration].
69 final Curve curve;
70
71 /// A widget to be placed inside the drawer header, inset by the [padding].
72 ///
73 /// This widget will be sized to the size of the header. To position the child
74 /// precisely, consider using an [Align] or [Center] widget.
75 ///
76 /// {@macro flutter.widgets.ProxyWidget.child}
77 final Widget? child;
78
79 @override
80 Widget build(BuildContext context) {
81 assert(debugCheckHasMaterial(context));
82 assert(debugCheckHasMediaQuery(context));
83 final ThemeData theme = Theme.of(context);
84 final double statusBarHeight = MediaQuery.paddingOf(context).top;
85 return Container(
86 height: statusBarHeight + _kDrawerHeaderHeight,
87 margin: margin,
88 decoration: BoxDecoration(border: Border(bottom: Divider.createBorderSide(context))),
89 child: AnimatedContainer(
90 padding: padding.add(EdgeInsets.only(top: statusBarHeight)),
91 decoration: decoration,
92 duration: duration,
93 curve: curve,
94 child: child == null
95 ? null
96 : DefaultTextStyle(
97 style: theme.textTheme.bodyLarge!,
98 child: MediaQuery.removePadding(context: context, removeTop: true, child: child!),
99 ),
100 ),
101 );
102 }
103}
104