| // 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 'package:flutter/foundation.dart'; |
| import 'package:flutter/widgets.dart'; |
| |
| import 'theme.dart'; |
| |
| // Examples can assume: |
| // late BuildContext context; |
| |
| /// Used with [ExpansionTileTheme] to define default property values for |
| /// descendant [ExpansionTile] widgets. |
| /// |
| /// Descendant widgets obtain the current [ExpansionTileThemeData] object |
| /// using `ExpansionTileTheme.of(context)`. Instances of |
| /// [ExpansionTileThemeData] can be customized with |
| /// [ExpansionTileThemeData.copyWith]. |
| /// |
| /// A [ExpansionTileThemeData] is often specified as part of the |
| /// overall [Theme] with [ThemeData.expansionTileTheme]. |
| /// |
| /// All [ExpansionTileThemeData] properties are `null` by default. |
| /// When a theme property is null, the [ExpansionTile] will provide its own |
| /// default based on the overall [Theme]'s textTheme and |
| /// colorScheme. See the individual [ExpansionTile] properties for details. |
| /// |
| /// See also: |
| /// |
| /// * [ThemeData], which describes the overall theme information for the |
| /// application. |
| /// * [ExpansionTileTheme] which overrides the default [ExpansionTileTheme] |
| /// of its [ExpansionTile] descendants. |
| /// * [ThemeData.textTheme], text with a color that contrasts with the card |
| /// and canvas colors. |
| /// * [ThemeData.colorScheme], the thirteen colors that most Material widget |
| /// default colors are based on. |
| @immutable |
| class ExpansionTileThemeData with Diagnosticable { |
| /// Creates a [ExpansionTileThemeData]. |
| const ExpansionTileThemeData ({ |
| this.backgroundColor, |
| this.collapsedBackgroundColor, |
| this.tilePadding, |
| this.expandedAlignment, |
| this.childrenPadding, |
| this.iconColor, |
| this.collapsedIconColor, |
| this.textColor, |
| this.collapsedTextColor, |
| this.shape, |
| this.collapsedShape, |
| this.clipBehavior, |
| }); |
| |
| /// Overrides the default value of [ExpansionTile.backgroundColor]. |
| final Color? backgroundColor; |
| |
| /// Overrides the default value of [ExpansionTile.collapsedBackgroundColor]. |
| final Color? collapsedBackgroundColor; |
| |
| /// Overrides the default value of [ExpansionTile.tilePadding]. |
| final EdgeInsetsGeometry? tilePadding; |
| |
| /// Overrides the default value of [ExpansionTile.expandedAlignment]. |
| final AlignmentGeometry? expandedAlignment; |
| |
| /// Overrides the default value of [ExpansionTile.childrenPadding]. |
| final EdgeInsetsGeometry? childrenPadding; |
| |
| /// Overrides the default value of [ExpansionTile.iconColor]. |
| final Color? iconColor; |
| |
| /// Overrides the default value of [ExpansionTile.collapsedIconColor]. |
| final Color? collapsedIconColor; |
| |
| /// Overrides the default value of [ExpansionTile.textColor]. |
| final Color? textColor; |
| |
| /// Overrides the default value of [ExpansionTile.collapsedTextColor]. |
| final Color? collapsedTextColor; |
| |
| /// Overrides the default value of [ExpansionTile.shape]. |
| final ShapeBorder? shape; |
| |
| /// Overrides the default value of [ExpansionTile.collapsedShape]. |
| final ShapeBorder? collapsedShape; |
| |
| /// Overrides the default value of [ExpansionTile.clipBehavior]. |
| final Clip? clipBehavior; |
| |
| /// Creates a copy of this object with the given fields replaced with the |
| /// new values. |
| ExpansionTileThemeData copyWith({ |
| Color? backgroundColor, |
| Color? collapsedBackgroundColor, |
| EdgeInsetsGeometry? tilePadding, |
| AlignmentGeometry? expandedAlignment, |
| EdgeInsetsGeometry? childrenPadding, |
| Color? iconColor, |
| Color? collapsedIconColor, |
| Color? textColor, |
| Color? collapsedTextColor, |
| ShapeBorder? shape, |
| ShapeBorder? collapsedShape, |
| Clip? clipBehavior, |
| }) { |
| return ExpansionTileThemeData( |
| backgroundColor: backgroundColor ?? this.backgroundColor, |
| collapsedBackgroundColor: collapsedBackgroundColor ?? this.collapsedBackgroundColor, |
| tilePadding: tilePadding ?? this.tilePadding, |
| expandedAlignment: expandedAlignment ?? this.expandedAlignment, |
| childrenPadding: childrenPadding ?? this.childrenPadding, |
| iconColor: iconColor ?? this.iconColor, |
| collapsedIconColor: collapsedIconColor ?? this.collapsedIconColor, |
| textColor: textColor ?? this.textColor, |
| collapsedTextColor: collapsedTextColor ?? this.collapsedTextColor, |
| shape: shape ?? this.shape, |
| collapsedShape: collapsedShape ?? this.collapsedShape, |
| clipBehavior: clipBehavior ?? this.clipBehavior, |
| ); |
| } |
| |
| /// Linearly interpolate between ExpansionTileThemeData objects. |
| static ExpansionTileThemeData? lerp(ExpansionTileThemeData? a, ExpansionTileThemeData? b, double t) { |
| if (identical(a, b)) { |
| return a; |
| } |
| return ExpansionTileThemeData( |
| backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t), |
| collapsedBackgroundColor: Color.lerp(a?.collapsedBackgroundColor, b?.collapsedBackgroundColor, t), |
| tilePadding: EdgeInsetsGeometry.lerp(a?.tilePadding, b?.tilePadding, t), |
| expandedAlignment: AlignmentGeometry.lerp(a?.expandedAlignment, b?.expandedAlignment, t), |
| childrenPadding: EdgeInsetsGeometry.lerp(a?.childrenPadding, b?.childrenPadding, t), |
| iconColor: Color.lerp(a?.iconColor, b?.iconColor, t), |
| collapsedIconColor: Color.lerp(a?.collapsedIconColor, b?.collapsedIconColor, t), |
| textColor: Color.lerp(a?.textColor, b?.textColor, t), |
| collapsedTextColor: Color.lerp(a?.collapsedTextColor, b?.collapsedTextColor, t), |
| shape: ShapeBorder.lerp(a?.shape, b?.shape, t), |
| collapsedShape: ShapeBorder.lerp(a?.collapsedShape, b?.collapsedShape, t), |
| ); |
| } |
| |
| @override |
| int get hashCode { |
| return Object.hash( |
| backgroundColor, |
| collapsedBackgroundColor, |
| tilePadding, |
| expandedAlignment, |
| childrenPadding, |
| iconColor, |
| collapsedIconColor, |
| textColor, |
| collapsedTextColor, |
| shape, |
| collapsedShape, |
| clipBehavior, |
| ); |
| } |
| |
| @override |
| bool operator ==(Object other) { |
| if (identical(this, other)) { |
| return true; |
| } |
| if (other.runtimeType != runtimeType) { |
| return false; |
| } |
| return other is ExpansionTileThemeData |
| && other.backgroundColor == backgroundColor |
| && other.collapsedBackgroundColor == collapsedBackgroundColor |
| && other.tilePadding == tilePadding |
| && other.expandedAlignment == expandedAlignment |
| && other.childrenPadding == childrenPadding |
| && other.iconColor == iconColor |
| && other.collapsedIconColor == collapsedIconColor |
| && other.textColor == textColor |
| && other.collapsedTextColor == collapsedTextColor |
| && other.shape == shape |
| && other.collapsedShape == collapsedShape |
| && other.clipBehavior == clipBehavior; |
| } |
| |
| @override |
| void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
| super.debugFillProperties(properties); |
| properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: null)); |
| properties.add(ColorProperty('collapsedBackgroundColor', collapsedBackgroundColor, defaultValue: null)); |
| properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('tilePadding', tilePadding, defaultValue: null)); |
| properties.add(DiagnosticsProperty<AlignmentGeometry>('expandedAlignment', expandedAlignment, defaultValue: null)); |
| properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('childrenPadding', childrenPadding, defaultValue: null)); |
| properties.add(ColorProperty('iconColor', iconColor, defaultValue: null)); |
| properties.add(ColorProperty('collapsedIconColor', collapsedIconColor, defaultValue: null)); |
| properties.add(ColorProperty('textColor', textColor, defaultValue: null)); |
| properties.add(ColorProperty('collapsedTextColor', collapsedTextColor, defaultValue: null)); |
| properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null)); |
| properties.add(DiagnosticsProperty<ShapeBorder>('collapsedShape', collapsedShape, defaultValue: null)); |
| properties.add(DiagnosticsProperty<Clip>('clipBehavior', clipBehavior, defaultValue: null)); |
| } |
| } |
| |
| /// Overrides the default [ExpansionTileTheme] of its [ExpansionTile] descendants. |
| /// |
| /// See also: |
| /// |
| /// * [ExpansionTileThemeData], which is used to configure this theme. |
| /// * [ThemeData.expansionTileTheme], which can be used to override the default |
| /// [ExpansionTileTheme] for [ExpansionTile]s below the overall [Theme]. |
| class ExpansionTileTheme extends InheritedTheme { |
| /// Applies the given theme [data] to [child]. |
| /// |
| /// The [data] and [child] arguments must not be null. |
| const ExpansionTileTheme({ |
| super.key, |
| required this.data, |
| required super.child, |
| }); |
| |
| /// Specifies color, alignment, and text style values for |
| /// descendant [ExpansionTile] widgets. |
| final ExpansionTileThemeData data; |
| |
| /// The closest instance of this class that encloses the given context. |
| /// |
| /// If there is no enclosing [ExpansionTileTheme] widget, then |
| /// [ThemeData.expansionTileTheme] is used. |
| /// |
| /// Typical usage is as follows: |
| /// |
| /// ```dart |
| /// ExpansionTileThemeData theme = ExpansionTileTheme.of(context); |
| /// ``` |
| static ExpansionTileThemeData of(BuildContext context) { |
| final ExpansionTileTheme? inheritedTheme = context.dependOnInheritedWidgetOfExactType<ExpansionTileTheme>(); |
| return inheritedTheme?.data ?? Theme.of(context).expansionTileTheme; |
| } |
| |
| @override |
| Widget wrap(BuildContext context, Widget child) { |
| return ExpansionTileTheme(data: data, child: child); |
| } |
| |
| @override |
| bool updateShouldNotify(ExpansionTileTheme oldWidget) => data != oldWidget.data; |
| } |