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
5import 'dart:ui' show lerpDouble;
6
7import 'package:flutter/foundation.dart';
8import 'package:flutter/rendering.dart';
9import 'package:flutter/widgets.dart';
10
11import 'material_state.dart';
12import 'navigation_bar.dart';
13import 'theme.dart';
14
15// Examples can assume:
16// late BuildContext context;
17
18/// Defines default property values for descendant [NavigationBar]
19/// widgets.
20///
21/// Descendant widgets obtain the current [NavigationBarThemeData] object
22/// using `NavigationBarTheme.of(context)`. Instances of
23/// [NavigationBarThemeData] can be customized with
24/// [NavigationBarThemeData.copyWith].
25///
26/// Typically a [NavigationBarThemeData] is specified as part of the
27/// overall [Theme] with [ThemeData.navigationBarTheme]. Alternatively, a
28/// [NavigationBarTheme] inherited widget can be used to theme [NavigationBar]s
29/// in a subtree of widgets.
30///
31/// All [NavigationBarThemeData] properties are `null` by default.
32/// When null, the [NavigationBar] will provide its own defaults based on the
33/// overall [Theme]'s textTheme and colorScheme. See the individual
34/// [NavigationBar] properties for details.
35///
36/// See also:
37///
38/// * [ThemeData], which describes the overall theme information for the
39/// application.
40@immutable
41class NavigationBarThemeData with Diagnosticable {
42 /// Creates a theme that can be used for [ThemeData.navigationBarTheme] and
43 /// [NavigationBarTheme].
44 const NavigationBarThemeData({
45 this.height,
46 this.backgroundColor,
47 this.elevation,
48 this.shadowColor,
49 this.surfaceTintColor,
50 this.indicatorColor,
51 this.indicatorShape,
52 this.labelTextStyle,
53 this.iconTheme,
54 this.labelBehavior,
55 this.overlayColor,
56 this.labelPadding,
57 });
58
59 /// Overrides the default value of [NavigationBar.height].
60 final double? height;
61
62 /// Overrides the default value of [NavigationBar.backgroundColor].
63 final Color? backgroundColor;
64
65 /// Overrides the default value of [NavigationBar.elevation].
66 final double? elevation;
67
68 /// Overrides the default value of [NavigationBar.shadowColor].
69 final Color? shadowColor;
70
71 /// Overrides the default value of [NavigationBar.surfaceTintColor].
72 final Color? surfaceTintColor;
73
74 /// Overrides the default value of [NavigationBar]'s selection indicator.
75 final Color? indicatorColor;
76
77 /// Overrides the default shape of the [NavigationBar]'s selection indicator.
78 final ShapeBorder? indicatorShape;
79
80 /// The style to merge with the default text style for
81 /// [NavigationDestination] labels.
82 ///
83 /// You can use this to specify a different style when the label is selected.
84 final MaterialStateProperty<TextStyle?>? labelTextStyle;
85
86 /// The theme to merge with the default icon theme for
87 /// [NavigationDestination] icons.
88 ///
89 /// You can use this to specify a different icon theme when the icon is
90 /// selected.
91 final MaterialStateProperty<IconThemeData?>? iconTheme;
92
93 /// Overrides the default value of [NavigationBar.labelBehavior].
94 final NavigationDestinationLabelBehavior? labelBehavior;
95
96 /// Overrides the default value of [NavigationBar.overlayColor].
97 final MaterialStateProperty<Color?>? overlayColor;
98
99 /// Overrides the default value of [NavigationBar.labelPadding].
100 final EdgeInsetsGeometry? labelPadding;
101
102 /// Creates a copy of this object with the given fields replaced with the
103 /// new values.
104 NavigationBarThemeData copyWith({
105 double? height,
106 Color? backgroundColor,
107 double? elevation,
108 Color? shadowColor,
109 Color? surfaceTintColor,
110 Color? indicatorColor,
111 ShapeBorder? indicatorShape,
112 MaterialStateProperty<TextStyle?>? labelTextStyle,
113 MaterialStateProperty<IconThemeData?>? iconTheme,
114 NavigationDestinationLabelBehavior? labelBehavior,
115 MaterialStateProperty<Color?>? overlayColor,
116 EdgeInsetsGeometry? labelPadding,
117 }) {
118 return NavigationBarThemeData(
119 height: height ?? this.height,
120 backgroundColor: backgroundColor ?? this.backgroundColor,
121 elevation: elevation ?? this.elevation,
122 shadowColor: shadowColor ?? this.shadowColor,
123 surfaceTintColor: surfaceTintColor ?? this.surfaceTintColor,
124 indicatorColor: indicatorColor ?? this.indicatorColor,
125 indicatorShape: indicatorShape ?? this.indicatorShape,
126 labelTextStyle: labelTextStyle ?? this.labelTextStyle,
127 iconTheme: iconTheme ?? this.iconTheme,
128 labelBehavior: labelBehavior ?? this.labelBehavior,
129 overlayColor: overlayColor ?? this.overlayColor,
130 labelPadding: labelPadding ?? this.labelPadding,
131 );
132 }
133
134 /// Linearly interpolate between two navigation rail themes.
135 ///
136 /// If both arguments are null then null is returned.
137 ///
138 /// {@macro dart.ui.shadow.lerp}
139 static NavigationBarThemeData? lerp(
140 NavigationBarThemeData? a,
141 NavigationBarThemeData? b,
142 double t,
143 ) {
144 if (identical(a, b)) {
145 return a;
146 }
147 return NavigationBarThemeData(
148 height: lerpDouble(a?.height, b?.height, t),
149 backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t),
150 elevation: lerpDouble(a?.elevation, b?.elevation, t),
151 shadowColor: Color.lerp(a?.shadowColor, b?.shadowColor, t),
152 surfaceTintColor: Color.lerp(a?.surfaceTintColor, b?.surfaceTintColor, t),
153 indicatorColor: Color.lerp(a?.indicatorColor, b?.indicatorColor, t),
154 indicatorShape: ShapeBorder.lerp(a?.indicatorShape, b?.indicatorShape, t),
155 labelTextStyle: MaterialStateProperty.lerp<TextStyle?>(
156 a?.labelTextStyle,
157 b?.labelTextStyle,
158 t,
159 TextStyle.lerp,
160 ),
161 iconTheme: MaterialStateProperty.lerp<IconThemeData?>(
162 a?.iconTheme,
163 b?.iconTheme,
164 t,
165 IconThemeData.lerp,
166 ),
167 labelBehavior: t < 0.5 ? a?.labelBehavior : b?.labelBehavior,
168 overlayColor: MaterialStateProperty.lerp<Color?>(
169 a?.overlayColor,
170 b?.overlayColor,
171 t,
172 Color.lerp,
173 ),
174 labelPadding: EdgeInsetsGeometry.lerp(a?.labelPadding, b?.labelPadding, t),
175 );
176 }
177
178 @override
179 int get hashCode => Object.hash(
180 height,
181 backgroundColor,
182 elevation,
183 shadowColor,
184 surfaceTintColor,
185 indicatorColor,
186 indicatorShape,
187 labelTextStyle,
188 iconTheme,
189 labelBehavior,
190 overlayColor,
191 labelPadding,
192 );
193
194 @override
195 bool operator ==(Object other) {
196 if (identical(this, other)) {
197 return true;
198 }
199 if (other.runtimeType != runtimeType) {
200 return false;
201 }
202 return other is NavigationBarThemeData &&
203 other.height == height &&
204 other.backgroundColor == backgroundColor &&
205 other.elevation == elevation &&
206 other.shadowColor == shadowColor &&
207 other.surfaceTintColor == surfaceTintColor &&
208 other.indicatorColor == indicatorColor &&
209 other.indicatorShape == indicatorShape &&
210 other.labelTextStyle == labelTextStyle &&
211 other.iconTheme == iconTheme &&
212 other.labelBehavior == labelBehavior &&
213 other.overlayColor == overlayColor &&
214 other.labelPadding == labelPadding;
215 }
216
217 @override
218 void debugFillProperties(DiagnosticPropertiesBuilder properties) {
219 super.debugFillProperties(properties);
220 properties.add(DoubleProperty('height', height, defaultValue: null));
221 properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: null));
222 properties.add(DoubleProperty('elevation', elevation, defaultValue: null));
223 properties.add(ColorProperty('shadowColor', shadowColor, defaultValue: null));
224 properties.add(ColorProperty('surfaceTintColor', surfaceTintColor, defaultValue: null));
225 properties.add(ColorProperty('indicatorColor', indicatorColor, defaultValue: null));
226 properties.add(
227 DiagnosticsProperty<ShapeBorder>('indicatorShape', indicatorShape, defaultValue: null),
228 );
229 properties.add(
230 DiagnosticsProperty<MaterialStateProperty<TextStyle?>>(
231 'labelTextStyle',
232 labelTextStyle,
233 defaultValue: null,
234 ),
235 );
236 properties.add(
237 DiagnosticsProperty<MaterialStateProperty<IconThemeData?>>(
238 'iconTheme',
239 iconTheme,
240 defaultValue: null,
241 ),
242 );
243 properties.add(
244 DiagnosticsProperty<NavigationDestinationLabelBehavior>(
245 'labelBehavior',
246 labelBehavior,
247 defaultValue: null,
248 ),
249 );
250 properties.add(
251 DiagnosticsProperty<MaterialStateProperty<Color?>>(
252 'overlayColor',
253 overlayColor,
254 defaultValue: null,
255 ),
256 );
257 properties.add(
258 DiagnosticsProperty<EdgeInsetsGeometry>('labelPadding', labelPadding, defaultValue: null),
259 );
260 }
261}
262
263/// An inherited widget that defines visual properties for [NavigationBar]s and
264/// [NavigationDestination]s in this widget's subtree.
265///
266/// Values specified here are used for [NavigationBar] properties that are not
267/// given an explicit non-null value.
268///
269/// See also:
270///
271/// * [ThemeData.navigationBarTheme], which describes the
272/// [NavigationBarThemeData] in the overall theme for the application.
273class NavigationBarTheme extends InheritedTheme {
274 /// Creates a navigation rail theme that controls the
275 /// [NavigationBarThemeData] properties for a [NavigationBar].
276 const NavigationBarTheme({super.key, required this.data, required super.child});
277
278 /// Specifies the background color, label text style, icon theme, and label
279 /// type values for descendant [NavigationBar] widgets.
280 final NavigationBarThemeData data;
281
282 /// The closest instance of this class that encloses the given context.
283 ///
284 /// If there is no enclosing [NavigationBarTheme] widget, then
285 /// [ThemeData.navigationBarTheme] is used.
286 ///
287 /// Typical usage is as follows:
288 ///
289 /// ```dart
290 /// NavigationBarThemeData theme = NavigationBarTheme.of(context);
291 /// ```
292 static NavigationBarThemeData of(BuildContext context) {
293 final NavigationBarTheme? navigationBarTheme =
294 context.dependOnInheritedWidgetOfExactType<NavigationBarTheme>();
295 return navigationBarTheme?.data ?? Theme.of(context).navigationBarTheme;
296 }
297
298 @override
299 Widget wrap(BuildContext context, Widget child) {
300 return NavigationBarTheme(data: data, child: child);
301 }
302
303 @override
304 bool updateShouldNotify(NavigationBarTheme oldWidget) => data != oldWidget.data;
305}
306

Provided by KDAB

Privacy Policy
Learn more about Flutter for embedded and desktop on industrialflutter.com