blob: 86c408b2047b04c687b2cc9b9bc07865e099f8d3 [file] [log] [blame]
// 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,
});
/// 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;
/// 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,
}) {
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,
);
}
/// Linearly interpolate between ExpansionTileThemeData objects.
static ExpansionTileThemeData? lerp(ExpansionTileThemeData? a, ExpansionTileThemeData? b, double t) {
assert (t != null);
if (a == null && b == null) {
return null;
}
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),
);
}
@override
int get hashCode {
return Object.hash(
backgroundColor,
collapsedBackgroundColor,
tilePadding,
expandedAlignment,
childrenPadding,
iconColor,
collapsedIconColor,
textColor,
collapsedTextColor,
);
}
@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;
}
@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));
}
}
/// 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,
}) : assert(child != null),
assert(data != null);
/// 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;
}