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

Provided by KDAB

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