| // Copyright 2014 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'dart:ui' show lerpDouble; |
| |
| import 'package:flutter/foundation.dart'; |
| import 'package:flutter/widgets.dart'; |
| |
| import 'bottom_navigation_bar.dart'; |
| import 'material_state.dart'; |
| import 'theme.dart'; |
| |
| // Examples can assume: |
| // late BuildContext context; |
| |
| /// Defines default property values for descendant [BottomNavigationBar] |
| /// widgets. |
| /// |
| /// Descendant widgets obtain the current [BottomNavigationBarThemeData] object |
| /// using `BottomNavigationBarTheme.of(context)`. Instances of |
| /// [BottomNavigationBarThemeData] can be customized with |
| /// [BottomNavigationBarThemeData.copyWith]. |
| /// |
| /// Typically a [BottomNavigationBarThemeData] is specified as part of the |
| /// overall [Theme] with [ThemeData.bottomNavigationBarTheme]. |
| /// |
| /// All [BottomNavigationBarThemeData] properties are `null` by default. When |
| /// null, the [BottomNavigationBar]'s build method provides defaults. |
| /// |
| /// See also: |
| /// |
| /// * [ThemeData], which describes the overall theme information for the |
| /// application. |
| @immutable |
| class BottomNavigationBarThemeData with Diagnosticable { |
| /// Creates a theme that can be used for [ThemeData.bottomNavigationBarTheme]. |
| const BottomNavigationBarThemeData({ |
| this.backgroundColor, |
| this.elevation, |
| this.selectedIconTheme, |
| this.unselectedIconTheme, |
| this.selectedItemColor, |
| this.unselectedItemColor, |
| this.selectedLabelStyle, |
| this.unselectedLabelStyle, |
| this.showSelectedLabels, |
| this.showUnselectedLabels, |
| this.type, |
| this.enableFeedback, |
| this.landscapeLayout, |
| this.mouseCursor, |
| }); |
| |
| /// The color of the [BottomNavigationBar] itself. |
| /// |
| /// See [BottomNavigationBar.backgroundColor]. |
| final Color? backgroundColor; |
| |
| /// The z-coordinate of the [BottomNavigationBar]. |
| /// |
| /// See [BottomNavigationBar.elevation]. |
| final double? elevation; |
| |
| /// The size, opacity, and color of the icon in the currently selected |
| /// [BottomNavigationBarItem.icon]. |
| /// |
| /// If [BottomNavigationBar.selectedIconTheme] is non-null on the widget, |
| /// the whole [IconThemeData] from the widget will be used over this |
| /// [selectedIconTheme]. |
| /// |
| /// See [BottomNavigationBar.selectedIconTheme]. |
| final IconThemeData? selectedIconTheme; |
| |
| /// The size, opacity, and color of the icon in the currently unselected |
| /// [BottomNavigationBarItem.icon]s. |
| /// |
| /// If [BottomNavigationBar.unselectedIconTheme] is non-null on the widget, |
| /// the whole [IconThemeData] from the widget will be used over this |
| /// [unselectedIconTheme]. |
| /// |
| /// See [BottomNavigationBar.unselectedIconTheme]. |
| final IconThemeData? unselectedIconTheme; |
| |
| /// The color of the selected [BottomNavigationBarItem.icon] and |
| /// [BottomNavigationBarItem.label]. |
| /// |
| /// See [BottomNavigationBar.selectedItemColor]. |
| final Color? selectedItemColor; |
| |
| /// The color of the unselected [BottomNavigationBarItem.icon] and |
| /// [BottomNavigationBarItem.label]s. |
| /// |
| /// See [BottomNavigationBar.unselectedItemColor]. |
| final Color? unselectedItemColor; |
| |
| /// The [TextStyle] of the [BottomNavigationBarItem] labels when they are |
| /// selected. |
| /// |
| /// See [BottomNavigationBar.selectedLabelStyle]. |
| final TextStyle? selectedLabelStyle; |
| |
| /// The [TextStyle] of the [BottomNavigationBarItem] labels when they are not |
| /// selected. |
| /// |
| /// See [BottomNavigationBar.unselectedLabelStyle]. |
| final TextStyle? unselectedLabelStyle; |
| |
| /// Whether the labels are shown for the selected [BottomNavigationBarItem]. |
| /// |
| /// See [BottomNavigationBar.showSelectedLabels]. |
| final bool? showSelectedLabels; |
| |
| /// Whether the labels are shown for the unselected [BottomNavigationBarItem]s. |
| /// |
| /// See [BottomNavigationBar.showUnselectedLabels]. |
| final bool? showUnselectedLabels; |
| |
| /// Defines the layout and behavior of a [BottomNavigationBar]. |
| /// |
| /// See [BottomNavigationBar.type]. |
| final BottomNavigationBarType? type; |
| |
| /// If specified, defines the feedback property for [BottomNavigationBar]. |
| /// |
| /// If [BottomNavigationBar.enableFeedback] is provided, [enableFeedback] is ignored. |
| final bool? enableFeedback; |
| |
| /// If non-null, overrides the [BottomNavigationBar.landscapeLayout] property. |
| final BottomNavigationBarLandscapeLayout? landscapeLayout; |
| |
| /// If specified, overrides the default value of [BottomNavigationBar.mouseCursor]. |
| final MaterialStateProperty<MouseCursor?>? mouseCursor; |
| |
| /// Creates a copy of this object but with the given fields replaced with the |
| /// new values. |
| BottomNavigationBarThemeData copyWith({ |
| Color? backgroundColor, |
| double? elevation, |
| IconThemeData? selectedIconTheme, |
| IconThemeData? unselectedIconTheme, |
| Color? selectedItemColor, |
| Color? unselectedItemColor, |
| TextStyle? selectedLabelStyle, |
| TextStyle? unselectedLabelStyle, |
| bool? showSelectedLabels, |
| bool? showUnselectedLabels, |
| BottomNavigationBarType? type, |
| bool? enableFeedback, |
| BottomNavigationBarLandscapeLayout? landscapeLayout, |
| MaterialStateProperty<MouseCursor?>? mouseCursor, |
| }) { |
| return BottomNavigationBarThemeData( |
| backgroundColor: backgroundColor ?? this.backgroundColor, |
| elevation: elevation ?? this.elevation, |
| selectedIconTheme: selectedIconTheme ?? this.selectedIconTheme, |
| unselectedIconTheme: unselectedIconTheme ?? this.unselectedIconTheme, |
| selectedItemColor: selectedItemColor ?? this.selectedItemColor, |
| unselectedItemColor: unselectedItemColor ?? this.unselectedItemColor, |
| selectedLabelStyle: selectedLabelStyle ?? this.selectedLabelStyle, |
| unselectedLabelStyle: unselectedLabelStyle ?? this.unselectedLabelStyle, |
| showSelectedLabels: showSelectedLabels ?? this.showSelectedLabels, |
| showUnselectedLabels: showUnselectedLabels ?? this.showUnselectedLabels, |
| type: type ?? this.type, |
| enableFeedback: enableFeedback ?? this.enableFeedback, |
| landscapeLayout: landscapeLayout ?? this.landscapeLayout, |
| mouseCursor: mouseCursor ?? this.mouseCursor, |
| ); |
| } |
| |
| /// Linearly interpolate between two [BottomNavigationBarThemeData]. |
| /// |
| /// The argument `t` must not be null. |
| /// |
| /// {@macro dart.ui.shadow.lerp} |
| static BottomNavigationBarThemeData lerp(BottomNavigationBarThemeData? a, BottomNavigationBarThemeData? b, double t) { |
| return BottomNavigationBarThemeData( |
| backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t), |
| elevation: lerpDouble(a?.elevation, b?.elevation, t), |
| selectedIconTheme: IconThemeData.lerp(a?.selectedIconTheme, b?.selectedIconTheme, t), |
| unselectedIconTheme: IconThemeData.lerp(a?.unselectedIconTheme, b?.unselectedIconTheme, t), |
| selectedItemColor: Color.lerp(a?.selectedItemColor, b?.selectedItemColor, t), |
| unselectedItemColor: Color.lerp(a?.unselectedItemColor, b?.unselectedItemColor, t), |
| selectedLabelStyle: TextStyle.lerp(a?.selectedLabelStyle, b?.selectedLabelStyle, t), |
| unselectedLabelStyle: TextStyle.lerp(a?.unselectedLabelStyle, b?.unselectedLabelStyle, t), |
| showSelectedLabels: t < 0.5 ? a?.showSelectedLabels : b?.showSelectedLabels, |
| showUnselectedLabels: t < 0.5 ? a?.showUnselectedLabels : b?.showUnselectedLabels, |
| type: t < 0.5 ? a?.type : b?.type, |
| enableFeedback: t < 0.5 ? a?.enableFeedback : b?.enableFeedback, |
| landscapeLayout: t < 0.5 ? a?.landscapeLayout : b?.landscapeLayout, |
| mouseCursor: t < 0.5 ? a?.mouseCursor : b?.mouseCursor, |
| ); |
| } |
| |
| @override |
| int get hashCode => Object.hash( |
| backgroundColor, |
| elevation, |
| selectedIconTheme, |
| unselectedIconTheme, |
| selectedItemColor, |
| unselectedItemColor, |
| selectedLabelStyle, |
| unselectedLabelStyle, |
| showSelectedLabels, |
| showUnselectedLabels, |
| type, |
| enableFeedback, |
| landscapeLayout, |
| mouseCursor, |
| ); |
| |
| @override |
| bool operator ==(Object other) { |
| if (identical(this, other)) { |
| return true; |
| } |
| if (other.runtimeType != runtimeType) { |
| return false; |
| } |
| return other is BottomNavigationBarThemeData |
| && other.backgroundColor == backgroundColor |
| && other.elevation == elevation |
| && other.selectedIconTheme == selectedIconTheme |
| && other.unselectedIconTheme == unselectedIconTheme |
| && other.selectedItemColor == selectedItemColor |
| && other.unselectedItemColor == unselectedItemColor |
| && other.selectedLabelStyle == selectedLabelStyle |
| && other.unselectedLabelStyle == unselectedLabelStyle |
| && other.showSelectedLabels == showSelectedLabels |
| && other.showUnselectedLabels == showUnselectedLabels |
| && other.type == type |
| && other.enableFeedback == enableFeedback |
| && other.landscapeLayout == landscapeLayout |
| && other.mouseCursor == mouseCursor; |
| } |
| |
| @override |
| void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
| super.debugFillProperties(properties); |
| properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: null)); |
| properties.add(DoubleProperty('elevation', elevation, defaultValue: null)); |
| properties.add(DiagnosticsProperty<IconThemeData>('selectedIconTheme', selectedIconTheme, defaultValue: null)); |
| properties.add(DiagnosticsProperty<IconThemeData>('unselectedIconTheme', unselectedIconTheme, defaultValue: null)); |
| properties.add(ColorProperty('selectedItemColor', selectedItemColor, defaultValue: null)); |
| properties.add(ColorProperty('unselectedItemColor', unselectedItemColor, defaultValue: null)); |
| properties.add(DiagnosticsProperty<TextStyle>('selectedLabelStyle', selectedLabelStyle, defaultValue: null)); |
| properties.add(DiagnosticsProperty<TextStyle>('unselectedLabelStyle', unselectedLabelStyle, defaultValue: null)); |
| properties.add(DiagnosticsProperty<bool>('showSelectedLabels', showSelectedLabels, defaultValue: null)); |
| properties.add(DiagnosticsProperty<bool>('showUnselectedLabels', showUnselectedLabels, defaultValue: null)); |
| properties.add(DiagnosticsProperty<BottomNavigationBarType>('type', type, defaultValue: null)); |
| properties.add(DiagnosticsProperty<bool>('enableFeedback', enableFeedback, defaultValue: null)); |
| properties.add(DiagnosticsProperty<BottomNavigationBarLandscapeLayout>('landscapeLayout', landscapeLayout, defaultValue: null)); |
| properties.add(DiagnosticsProperty<MaterialStateProperty<MouseCursor?>>('mouseCursor', mouseCursor, defaultValue: null)); |
| } |
| } |
| |
| /// Applies a bottom navigation bar theme to descendant [BottomNavigationBar] |
| /// widgets. |
| /// |
| /// Descendant widgets obtain the current theme's [BottomNavigationBarTheme] |
| /// object using [BottomNavigationBarTheme.of]. When a widget uses |
| /// [BottomNavigationBarTheme.of], it is automatically rebuilt if the theme |
| /// later changes. |
| /// |
| /// A bottom navigation theme can be specified as part of the overall Material |
| /// theme using [ThemeData.bottomNavigationBarTheme]. |
| /// |
| /// See also: |
| /// |
| /// * [BottomNavigationBarThemeData], which describes the actual configuration |
| /// of a bottom navigation bar theme. |
| class BottomNavigationBarTheme extends InheritedWidget { |
| /// Constructs a bottom navigation bar theme that configures all descendant |
| /// [BottomNavigationBar] widgets. |
| /// |
| /// The [data] must not be null. |
| const BottomNavigationBarTheme({ |
| super.key, |
| required this.data, |
| required super.child, |
| }); |
| |
| /// The properties used for all descendant [BottomNavigationBar] widgets. |
| final BottomNavigationBarThemeData data; |
| |
| /// Returns the configuration [data] from the closest |
| /// [BottomNavigationBarTheme] ancestor. If there is no ancestor, it returns |
| /// [ThemeData.bottomNavigationBarTheme]. Applications can assume that the |
| /// returned value will not be null. |
| /// |
| /// Typical usage is as follows: |
| /// |
| /// ```dart |
| /// BottomNavigationBarThemeData theme = BottomNavigationBarTheme.of(context); |
| /// ``` |
| static BottomNavigationBarThemeData of(BuildContext context) { |
| final BottomNavigationBarTheme? bottomNavTheme = context.dependOnInheritedWidgetOfExactType<BottomNavigationBarTheme>(); |
| return bottomNavTheme?.data ?? Theme.of(context).bottomNavigationBarTheme; |
| } |
| |
| @override |
| bool updateShouldNotify(BottomNavigationBarTheme oldWidget) => data != oldWidget.data; |
| } |