Add ExpansionTileTheme
(#98405)
This commit is contained in:
parent
2a2f973120
commit
60f039cb1c
@ -73,6 +73,7 @@ export 'src/material/elevation_overlay.dart';
|
|||||||
export 'src/material/expand_icon.dart';
|
export 'src/material/expand_icon.dart';
|
||||||
export 'src/material/expansion_panel.dart';
|
export 'src/material/expansion_panel.dart';
|
||||||
export 'src/material/expansion_tile.dart';
|
export 'src/material/expansion_tile.dart';
|
||||||
|
export 'src/material/expansion_tile_theme.dart';
|
||||||
export 'src/material/feedback.dart';
|
export 'src/material/feedback.dart';
|
||||||
export 'src/material/flat_button.dart';
|
export 'src/material/flat_button.dart';
|
||||||
export 'src/material/flexible_space_bar.dart';
|
export 'src/material/flexible_space_bar.dart';
|
||||||
|
@ -6,6 +6,7 @@ import 'package:flutter/widgets.dart';
|
|||||||
|
|
||||||
import 'color_scheme.dart';
|
import 'color_scheme.dart';
|
||||||
import 'colors.dart';
|
import 'colors.dart';
|
||||||
|
import 'expansion_tile_theme.dart';
|
||||||
import 'icons.dart';
|
import 'icons.dart';
|
||||||
import 'list_tile.dart';
|
import 'list_tile.dart';
|
||||||
import 'theme.dart';
|
import 'theme.dart';
|
||||||
@ -107,9 +108,25 @@ class ExpansionTile extends StatefulWidget {
|
|||||||
final List<Widget> children;
|
final List<Widget> children;
|
||||||
|
|
||||||
/// The color to display behind the sublist when expanded.
|
/// The color to display behind the sublist when expanded.
|
||||||
|
///
|
||||||
|
/// If this property is null then [ExpansionTileThemeData.backgroundColor] is used. If that
|
||||||
|
/// is also null then Colors.transparent is used.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [ExpansionTileTheme.of], which returns the nearest [ExpansionTileTheme]'s
|
||||||
|
/// [ExpansionTileThemeData].
|
||||||
final Color? backgroundColor;
|
final Color? backgroundColor;
|
||||||
|
|
||||||
/// When not null, defines the background color of tile when the sublist is collapsed.
|
/// When not null, defines the background color of tile when the sublist is collapsed.
|
||||||
|
///
|
||||||
|
/// If this property is null then [ExpansionTileThemeData.collapsedBackgroundColor] is used.
|
||||||
|
/// If that is also null then Colors.transparent is used.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [ExpansionTileTheme.of], which returns the nearest [ExpansionTileTheme]'s
|
||||||
|
/// [ExpansionTileThemeData].
|
||||||
final Color? collapsedBackgroundColor;
|
final Color? collapsedBackgroundColor;
|
||||||
|
|
||||||
/// A widget to display after the title.
|
/// A widget to display after the title.
|
||||||
@ -134,7 +151,13 @@ class ExpansionTile extends StatefulWidget {
|
|||||||
/// the [leading], [title], [subtitle] and [trailing] widgets. It does not inset
|
/// the [leading], [title], [subtitle] and [trailing] widgets. It does not inset
|
||||||
/// the expanded [children] widgets.
|
/// the expanded [children] widgets.
|
||||||
///
|
///
|
||||||
/// When the value is null, the tile's padding is `EdgeInsets.symmetric(horizontal: 16.0)`.
|
/// If this property is null then [ExpansionTileThemeData.tilePadding] is used. If that
|
||||||
|
/// is also null then the tile's padding is `EdgeInsets.symmetric(horizontal: 16.0)`.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [ExpansionTileTheme.of], which returns the nearest [ExpansionTileTheme]'s
|
||||||
|
/// [ExpansionTileThemeData].
|
||||||
final EdgeInsetsGeometry? tilePadding;
|
final EdgeInsetsGeometry? tilePadding;
|
||||||
|
|
||||||
/// Specifies the alignment of [children], which are arranged in a column when
|
/// Specifies the alignment of [children], which are arranged in a column when
|
||||||
@ -150,7 +173,13 @@ class ExpansionTile extends StatefulWidget {
|
|||||||
///
|
///
|
||||||
/// The width of the column is the width of the widest child widget in [children].
|
/// The width of the column is the width of the widest child widget in [children].
|
||||||
///
|
///
|
||||||
/// When the value is null, the value of `expandedAlignment` is [Alignment.center].
|
/// If this property is null then [ExpansionTileThemeData.expandedAlignment]is used. If that
|
||||||
|
/// is also null then the value of `expandedAlignment` is [Alignment.center].
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [ExpansionTileTheme.of], which returns the nearest [ExpansionTileTheme]'s
|
||||||
|
/// [ExpansionTileThemeData].
|
||||||
final Alignment? expandedAlignment;
|
final Alignment? expandedAlignment;
|
||||||
|
|
||||||
/// Specifies the alignment of each child within [children] when the tile is expanded.
|
/// Specifies the alignment of each child within [children] when the tile is expanded.
|
||||||
@ -171,12 +200,26 @@ class ExpansionTile extends StatefulWidget {
|
|||||||
|
|
||||||
/// Specifies padding for [children].
|
/// Specifies padding for [children].
|
||||||
///
|
///
|
||||||
/// When the value is null, the value of `childrenPadding` is [EdgeInsets.zero].
|
/// If this property is null then [ExpansionTileThemeData.childrenPadding] is used. If that
|
||||||
|
/// is also null then the value of `childrenPadding` is [EdgeInsets.zero].
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [ExpansionTileTheme.of], which returns the nearest [ExpansionTileTheme]'s
|
||||||
|
/// [ExpansionTileThemeData].
|
||||||
final EdgeInsetsGeometry? childrenPadding;
|
final EdgeInsetsGeometry? childrenPadding;
|
||||||
|
|
||||||
/// The icon color of tile's expansion arrow icon when the sublist is expanded.
|
/// The icon color of tile's expansion arrow icon when the sublist is expanded.
|
||||||
///
|
///
|
||||||
/// Used to override to the [ListTileThemeData.iconColor].
|
/// Used to override to the [ListTileThemeData.iconColor].
|
||||||
|
///
|
||||||
|
/// If this property is null then [ExpansionTileThemeData.iconColor] is used. If that
|
||||||
|
/// is also null then the value of [ListTileThemeData.iconColor] is used.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [ExpansionTileTheme.of], which returns the nearest [ExpansionTileTheme]'s
|
||||||
|
/// [ExpansionTileThemeData].
|
||||||
final Color? iconColor;
|
final Color? iconColor;
|
||||||
|
|
||||||
/// The icon color of tile's expansion arrow icon when the sublist is collapsed.
|
/// The icon color of tile's expansion arrow icon when the sublist is collapsed.
|
||||||
@ -188,11 +231,27 @@ class ExpansionTile extends StatefulWidget {
|
|||||||
/// The color of the tile's titles when the sublist is expanded.
|
/// The color of the tile's titles when the sublist is expanded.
|
||||||
///
|
///
|
||||||
/// Used to override to the [ListTileThemeData.textColor].
|
/// Used to override to the [ListTileThemeData.textColor].
|
||||||
|
///
|
||||||
|
/// If this property is null then [ExpansionTileThemeData.textColor] is used. If that
|
||||||
|
/// is also null then the value of [ListTileThemeData.textColor] is used.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [ExpansionTileTheme.of], which returns the nearest [ExpansionTileTheme]'s
|
||||||
|
/// [ExpansionTileThemeData].
|
||||||
final Color? textColor;
|
final Color? textColor;
|
||||||
|
|
||||||
/// The color of the tile's titles when the sublist is collapsed.
|
/// The color of the tile's titles when the sublist is collapsed.
|
||||||
///
|
///
|
||||||
/// Used to override to the [ListTileThemeData.textColor].
|
/// Used to override to the [ListTileThemeData.textColor].
|
||||||
|
///
|
||||||
|
/// If this property is null then [ExpansionTileThemeData.collapsedTextColor] is used. If that
|
||||||
|
/// is also null then the value of [ListTileThemeData.textColor] is used.
|
||||||
|
///
|
||||||
|
/// See also:
|
||||||
|
///
|
||||||
|
/// * [ExpansionTileTheme.of], which returns the nearest [ExpansionTileTheme]'s
|
||||||
|
/// [ExpansionTileThemeData].
|
||||||
final Color? collapsedTextColor;
|
final Color? collapsedTextColor;
|
||||||
|
|
||||||
/// Typically used to force the expansion arrow icon to the tile's leading or trailing edge.
|
/// Typically used to force the expansion arrow icon to the tile's leading or trailing edge.
|
||||||
@ -297,11 +356,12 @@ class _ExpansionTileState extends State<ExpansionTile> with SingleTickerProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildChildren(BuildContext context, Widget? child) {
|
Widget _buildChildren(BuildContext context, Widget? child) {
|
||||||
|
final ExpansionTileThemeData expansionTileTheme = ExpansionTileTheme.of(context);
|
||||||
final Color borderSideColor = _borderColor.value ?? Colors.transparent;
|
final Color borderSideColor = _borderColor.value ?? Colors.transparent;
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: _backgroundColor.value ?? Colors.transparent,
|
color: _backgroundColor.value ?? expansionTileTheme.backgroundColor ?? Colors.transparent,
|
||||||
border: Border(
|
border: Border(
|
||||||
top: BorderSide(color: borderSideColor),
|
top: BorderSide(color: borderSideColor),
|
||||||
bottom: BorderSide(color: borderSideColor),
|
bottom: BorderSide(color: borderSideColor),
|
||||||
@ -311,11 +371,11 @@ class _ExpansionTileState extends State<ExpansionTile> with SingleTickerProvider
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
ListTileTheme.merge(
|
ListTileTheme.merge(
|
||||||
iconColor: _iconColor.value,
|
iconColor: _iconColor.value ?? expansionTileTheme.iconColor,
|
||||||
textColor: _headerColor.value,
|
textColor: _headerColor.value,
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
onTap: _handleTap,
|
onTap: _handleTap,
|
||||||
contentPadding: widget.tilePadding,
|
contentPadding: widget.tilePadding ?? expansionTileTheme.tilePadding,
|
||||||
leading: widget.leading ?? _buildLeadingIcon(context),
|
leading: widget.leading ?? _buildLeadingIcon(context),
|
||||||
title: widget.title,
|
title: widget.title,
|
||||||
subtitle: widget.subtitle,
|
subtitle: widget.subtitle,
|
||||||
@ -324,7 +384,9 @@ class _ExpansionTileState extends State<ExpansionTile> with SingleTickerProvider
|
|||||||
),
|
),
|
||||||
ClipRect(
|
ClipRect(
|
||||||
child: Align(
|
child: Align(
|
||||||
alignment: widget.expandedAlignment ?? Alignment.center,
|
alignment: widget.expandedAlignment
|
||||||
|
?? expansionTileTheme.expandedAlignment
|
||||||
|
?? Alignment.center,
|
||||||
heightFactor: _heightFactor.value,
|
heightFactor: _heightFactor.value,
|
||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
@ -337,22 +399,28 @@ class _ExpansionTileState extends State<ExpansionTile> with SingleTickerProvider
|
|||||||
@override
|
@override
|
||||||
void didChangeDependencies() {
|
void didChangeDependencies() {
|
||||||
final ThemeData theme = Theme.of(context);
|
final ThemeData theme = Theme.of(context);
|
||||||
|
final ExpansionTileThemeData expansionTileTheme = ExpansionTileTheme.of(context);
|
||||||
final ColorScheme colorScheme = theme.colorScheme;
|
final ColorScheme colorScheme = theme.colorScheme;
|
||||||
_borderColorTween.end = theme.dividerColor;
|
_borderColorTween.end = theme.dividerColor;
|
||||||
_headerColorTween
|
_headerColorTween
|
||||||
..begin = widget.collapsedTextColor ?? theme.textTheme.subtitle1!.color
|
..begin = widget.collapsedTextColor
|
||||||
..end = widget.textColor ?? colorScheme.primary;
|
?? expansionTileTheme.collapsedTextColor
|
||||||
|
?? theme.textTheme.subtitle1!.color
|
||||||
|
..end = widget.textColor ?? expansionTileTheme.textColor ?? colorScheme.primary;
|
||||||
_iconColorTween
|
_iconColorTween
|
||||||
..begin = widget.collapsedIconColor ?? theme.unselectedWidgetColor
|
..begin = widget.collapsedIconColor
|
||||||
..end = widget.iconColor ?? colorScheme.primary;
|
?? expansionTileTheme.collapsedIconColor
|
||||||
|
?? theme.unselectedWidgetColor
|
||||||
|
..end = widget.iconColor ?? expansionTileTheme.iconColor ?? colorScheme.primary;
|
||||||
_backgroundColorTween
|
_backgroundColorTween
|
||||||
..begin = widget.collapsedBackgroundColor
|
..begin = widget.collapsedBackgroundColor ?? expansionTileTheme.collapsedBackgroundColor
|
||||||
..end = widget.backgroundColor;
|
..end = widget.backgroundColor ?? expansionTileTheme.backgroundColor;
|
||||||
super.didChangeDependencies();
|
super.didChangeDependencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final ExpansionTileThemeData expansionTileTheme = ExpansionTileTheme.of(context);
|
||||||
final bool closed = !_isExpanded && _controller.isDismissed;
|
final bool closed = !_isExpanded && _controller.isDismissed;
|
||||||
final bool shouldRemoveChildren = closed && !widget.maintainState;
|
final bool shouldRemoveChildren = closed && !widget.maintainState;
|
||||||
|
|
||||||
@ -361,7 +429,7 @@ class _ExpansionTileState extends State<ExpansionTile> with SingleTickerProvider
|
|||||||
child: TickerMode(
|
child: TickerMode(
|
||||||
enabled: !closed,
|
enabled: !closed,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: widget.childrenPadding ?? EdgeInsets.zero,
|
padding: widget.childrenPadding ?? expansionTileTheme.childrenPadding ?? EdgeInsets.zero,
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: widget.expandedCrossAxisAlignment ?? CrossAxisAlignment.center,
|
crossAxisAlignment: widget.expandedCrossAxisAlignment ?? CrossAxisAlignment.center,
|
||||||
children: widget.children,
|
children: widget.children,
|
||||||
|
217
packages/flutter/lib/src/material/expansion_tile_theme.dart
Normal file
217
packages/flutter/lib/src/material/expansion_tile_theme.dart
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
// 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';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
import 'theme.dart';
|
||||||
|
|
||||||
|
/// 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 hashValues(
|
||||||
|
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({
|
||||||
|
Key? key,
|
||||||
|
required this.data,
|
||||||
|
required Widget child,
|
||||||
|
}) : assert(child != null),
|
||||||
|
assert(data != null),
|
||||||
|
super(key: key, child: 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;
|
||||||
|
}
|
@ -24,6 +24,7 @@ import 'dialog_theme.dart';
|
|||||||
import 'divider_theme.dart';
|
import 'divider_theme.dart';
|
||||||
import 'drawer_theme.dart';
|
import 'drawer_theme.dart';
|
||||||
import 'elevated_button_theme.dart';
|
import 'elevated_button_theme.dart';
|
||||||
|
import 'expansion_tile_theme.dart';
|
||||||
import 'floating_action_button_theme.dart';
|
import 'floating_action_button_theme.dart';
|
||||||
import 'ink_splash.dart';
|
import 'ink_splash.dart';
|
||||||
import 'ink_well.dart' show InteractiveInkFeatureFactory;
|
import 'ink_well.dart' show InteractiveInkFeatureFactory;
|
||||||
@ -321,6 +322,7 @@ class ThemeData with Diagnosticable {
|
|||||||
TimePickerThemeData? timePickerTheme,
|
TimePickerThemeData? timePickerTheme,
|
||||||
ToggleButtonsThemeData? toggleButtonsTheme,
|
ToggleButtonsThemeData? toggleButtonsTheme,
|
||||||
TooltipThemeData? tooltipTheme,
|
TooltipThemeData? tooltipTheme,
|
||||||
|
ExpansionTileThemeData? expansionTileTheme,
|
||||||
// DEPRECATED (newest deprecations at the bottom)
|
// DEPRECATED (newest deprecations at the bottom)
|
||||||
@Deprecated(
|
@Deprecated(
|
||||||
'No longer used by the framework, please remove any reference to it. '
|
'No longer used by the framework, please remove any reference to it. '
|
||||||
@ -541,6 +543,7 @@ class ThemeData with Diagnosticable {
|
|||||||
timePickerTheme ??= const TimePickerThemeData();
|
timePickerTheme ??= const TimePickerThemeData();
|
||||||
toggleButtonsTheme ??= const ToggleButtonsThemeData();
|
toggleButtonsTheme ??= const ToggleButtonsThemeData();
|
||||||
tooltipTheme ??= const TooltipThemeData();
|
tooltipTheme ??= const TooltipThemeData();
|
||||||
|
expansionTileTheme ??= const ExpansionTileThemeData();
|
||||||
|
|
||||||
// DEPRECATED (newest deprecations at the bottom)
|
// DEPRECATED (newest deprecations at the bottom)
|
||||||
useTextSelectionTheme ??= true;
|
useTextSelectionTheme ??= true;
|
||||||
@ -630,6 +633,7 @@ class ThemeData with Diagnosticable {
|
|||||||
timePickerTheme: timePickerTheme,
|
timePickerTheme: timePickerTheme,
|
||||||
toggleButtonsTheme: toggleButtonsTheme,
|
toggleButtonsTheme: toggleButtonsTheme,
|
||||||
tooltipTheme: tooltipTheme,
|
tooltipTheme: tooltipTheme,
|
||||||
|
expansionTileTheme: expansionTileTheme,
|
||||||
// DEPRECATED (newest deprecations at the bottom)
|
// DEPRECATED (newest deprecations at the bottom)
|
||||||
useTextSelectionTheme: useTextSelectionTheme,
|
useTextSelectionTheme: useTextSelectionTheme,
|
||||||
textSelectionColor: textSelectionColor,
|
textSelectionColor: textSelectionColor,
|
||||||
@ -735,6 +739,7 @@ class ThemeData with Diagnosticable {
|
|||||||
required this.timePickerTheme,
|
required this.timePickerTheme,
|
||||||
required this.toggleButtonsTheme,
|
required this.toggleButtonsTheme,
|
||||||
required this.tooltipTheme,
|
required this.tooltipTheme,
|
||||||
|
required this.expansionTileTheme,
|
||||||
// DEPRECATED (newest deprecations at the bottom)
|
// DEPRECATED (newest deprecations at the bottom)
|
||||||
@Deprecated(
|
@Deprecated(
|
||||||
'No longer used by the framework, please remove any reference to it. '
|
'No longer used by the framework, please remove any reference to it. '
|
||||||
@ -873,6 +878,7 @@ class ThemeData with Diagnosticable {
|
|||||||
assert(timePickerTheme != null),
|
assert(timePickerTheme != null),
|
||||||
assert(toggleButtonsTheme != null),
|
assert(toggleButtonsTheme != null),
|
||||||
assert(tooltipTheme != null),
|
assert(tooltipTheme != null),
|
||||||
|
assert(expansionTileTheme != null),
|
||||||
// DEPRECATED (newest deprecations at the bottom)
|
// DEPRECATED (newest deprecations at the bottom)
|
||||||
assert(useTextSelectionTheme != null),
|
assert(useTextSelectionTheme != null),
|
||||||
assert(textSelectionColor != null),
|
assert(textSelectionColor != null),
|
||||||
@ -1409,6 +1415,9 @@ class ThemeData with Diagnosticable {
|
|||||||
/// This is the value returned from [TooltipTheme.of].
|
/// This is the value returned from [TooltipTheme.of].
|
||||||
final TooltipThemeData tooltipTheme;
|
final TooltipThemeData tooltipTheme;
|
||||||
|
|
||||||
|
/// A theme for customizing the visual properties of [ExpansionTile]s.
|
||||||
|
final ExpansionTileThemeData expansionTileTheme;
|
||||||
|
|
||||||
// DEPRECATED (newest deprecations at the bottom)
|
// DEPRECATED (newest deprecations at the bottom)
|
||||||
|
|
||||||
/// A temporary flag that was used to opt-in to the new [TextSelectionTheme]
|
/// A temporary flag that was used to opt-in to the new [TextSelectionTheme]
|
||||||
@ -1634,6 +1643,7 @@ class ThemeData with Diagnosticable {
|
|||||||
TimePickerThemeData? timePickerTheme,
|
TimePickerThemeData? timePickerTheme,
|
||||||
ToggleButtonsThemeData? toggleButtonsTheme,
|
ToggleButtonsThemeData? toggleButtonsTheme,
|
||||||
TooltipThemeData? tooltipTheme,
|
TooltipThemeData? tooltipTheme,
|
||||||
|
ExpansionTileThemeData? expansionTileTheme,
|
||||||
// DEPRECATED (newest deprecations at the bottom)
|
// DEPRECATED (newest deprecations at the bottom)
|
||||||
@Deprecated(
|
@Deprecated(
|
||||||
'No longer used by the framework, please remove any reference to it. '
|
'No longer used by the framework, please remove any reference to it. '
|
||||||
@ -1777,6 +1787,7 @@ class ThemeData with Diagnosticable {
|
|||||||
timePickerTheme: timePickerTheme ?? this.timePickerTheme,
|
timePickerTheme: timePickerTheme ?? this.timePickerTheme,
|
||||||
toggleButtonsTheme: toggleButtonsTheme ?? this.toggleButtonsTheme,
|
toggleButtonsTheme: toggleButtonsTheme ?? this.toggleButtonsTheme,
|
||||||
tooltipTheme: tooltipTheme ?? this.tooltipTheme,
|
tooltipTheme: tooltipTheme ?? this.tooltipTheme,
|
||||||
|
expansionTileTheme: expansionTileTheme ?? this.expansionTileTheme,
|
||||||
// DEPRECATED (newest deprecations at the bottom)
|
// DEPRECATED (newest deprecations at the bottom)
|
||||||
useTextSelectionTheme: useTextSelectionTheme ?? this.useTextSelectionTheme,
|
useTextSelectionTheme: useTextSelectionTheme ?? this.useTextSelectionTheme,
|
||||||
textSelectionColor: textSelectionColor ?? this.textSelectionColor,
|
textSelectionColor: textSelectionColor ?? this.textSelectionColor,
|
||||||
@ -1946,6 +1957,7 @@ class ThemeData with Diagnosticable {
|
|||||||
timePickerTheme: TimePickerThemeData.lerp(a.timePickerTheme, b.timePickerTheme, t),
|
timePickerTheme: TimePickerThemeData.lerp(a.timePickerTheme, b.timePickerTheme, t),
|
||||||
toggleButtonsTheme: ToggleButtonsThemeData.lerp(a.toggleButtonsTheme, b.toggleButtonsTheme, t)!,
|
toggleButtonsTheme: ToggleButtonsThemeData.lerp(a.toggleButtonsTheme, b.toggleButtonsTheme, t)!,
|
||||||
tooltipTheme: TooltipThemeData.lerp(a.tooltipTheme, b.tooltipTheme, t)!,
|
tooltipTheme: TooltipThemeData.lerp(a.tooltipTheme, b.tooltipTheme, t)!,
|
||||||
|
expansionTileTheme: ExpansionTileThemeData.lerp(a.expansionTileTheme, b.expansionTileTheme, t)!,
|
||||||
// DEPRECATED (newest deprecations at the bottom)
|
// DEPRECATED (newest deprecations at the bottom)
|
||||||
useTextSelectionTheme: t < 0.5 ? a.useTextSelectionTheme : b.useTextSelectionTheme,
|
useTextSelectionTheme: t < 0.5 ? a.useTextSelectionTheme : b.useTextSelectionTheme,
|
||||||
textSelectionColor: Color.lerp(a.textSelectionColor, b.textSelectionColor, t)!,
|
textSelectionColor: Color.lerp(a.textSelectionColor, b.textSelectionColor, t)!,
|
||||||
@ -2045,6 +2057,7 @@ class ThemeData with Diagnosticable {
|
|||||||
other.timePickerTheme == timePickerTheme &&
|
other.timePickerTheme == timePickerTheme &&
|
||||||
other.toggleButtonsTheme == toggleButtonsTheme &&
|
other.toggleButtonsTheme == toggleButtonsTheme &&
|
||||||
other.tooltipTheme == tooltipTheme &&
|
other.tooltipTheme == tooltipTheme &&
|
||||||
|
other.expansionTileTheme == expansionTileTheme &&
|
||||||
// DEPRECATED (newest deprecations at the bottom)
|
// DEPRECATED (newest deprecations at the bottom)
|
||||||
other.useTextSelectionTheme == useTextSelectionTheme &&
|
other.useTextSelectionTheme == useTextSelectionTheme &&
|
||||||
other.textSelectionColor == textSelectionColor &&
|
other.textSelectionColor == textSelectionColor &&
|
||||||
@ -2141,6 +2154,7 @@ class ThemeData with Diagnosticable {
|
|||||||
timePickerTheme,
|
timePickerTheme,
|
||||||
toggleButtonsTheme,
|
toggleButtonsTheme,
|
||||||
tooltipTheme,
|
tooltipTheme,
|
||||||
|
expansionTileTheme,
|
||||||
// DEPRECATED (newest deprecations at the bottom)
|
// DEPRECATED (newest deprecations at the bottom)
|
||||||
useTextSelectionTheme,
|
useTextSelectionTheme,
|
||||||
textSelectionColor,
|
textSelectionColor,
|
||||||
@ -2237,6 +2251,7 @@ class ThemeData with Diagnosticable {
|
|||||||
properties.add(DiagnosticsProperty<TimePickerThemeData>('timePickerTheme', timePickerTheme, defaultValue: defaultData.timePickerTheme, level: DiagnosticLevel.debug));
|
properties.add(DiagnosticsProperty<TimePickerThemeData>('timePickerTheme', timePickerTheme, defaultValue: defaultData.timePickerTheme, level: DiagnosticLevel.debug));
|
||||||
properties.add(DiagnosticsProperty<ToggleButtonsThemeData>('toggleButtonsTheme', toggleButtonsTheme, level: DiagnosticLevel.debug));
|
properties.add(DiagnosticsProperty<ToggleButtonsThemeData>('toggleButtonsTheme', toggleButtonsTheme, level: DiagnosticLevel.debug));
|
||||||
properties.add(DiagnosticsProperty<TooltipThemeData>('tooltipTheme', tooltipTheme, level: DiagnosticLevel.debug));
|
properties.add(DiagnosticsProperty<TooltipThemeData>('tooltipTheme', tooltipTheme, level: DiagnosticLevel.debug));
|
||||||
|
properties.add(DiagnosticsProperty<ExpansionTileThemeData>('expansionTileTheme', expansionTileTheme, level: DiagnosticLevel.debug));
|
||||||
// DEPRECATED (newest deprecations at the bottom)
|
// DEPRECATED (newest deprecations at the bottom)
|
||||||
properties.add(DiagnosticsProperty<bool>('useTextSelectionTheme', useTextSelectionTheme, level: DiagnosticLevel.debug));
|
properties.add(DiagnosticsProperty<bool>('useTextSelectionTheme', useTextSelectionTheme, level: DiagnosticLevel.debug));
|
||||||
properties.add(ColorProperty('textSelectionColor', textSelectionColor, defaultValue: defaultData.textSelectionColor, level: DiagnosticLevel.debug));
|
properties.add(ColorProperty('textSelectionColor', textSelectionColor, defaultValue: defaultData.textSelectionColor, level: DiagnosticLevel.debug));
|
||||||
|
257
packages/flutter/test/material/expansion_tile_theme_test.dart
Normal file
257
packages/flutter/test/material/expansion_tile_theme_test.dart
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
// 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/material.dart';
|
||||||
|
import 'package:flutter/rendering.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
class TestIcon extends StatefulWidget {
|
||||||
|
const TestIcon({Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
TestIconState createState() => TestIconState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestIconState extends State<TestIcon> {
|
||||||
|
late IconThemeData iconTheme;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
iconTheme = IconTheme.of(context);
|
||||||
|
return const Icon(Icons.expand_more);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class TestText extends StatefulWidget {
|
||||||
|
const TestText(this.text, {Key? key}) : super(key: key);
|
||||||
|
|
||||||
|
final String text;
|
||||||
|
|
||||||
|
@override
|
||||||
|
TestTextState createState() => TestTextState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestTextState extends State<TestText> {
|
||||||
|
late TextStyle textStyle;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
textStyle = DefaultTextStyle.of(context).style;
|
||||||
|
return Text(widget.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
test('ExpansionTileThemeData copyWith, ==, hashCode basics', () {
|
||||||
|
expect(const ExpansionTileThemeData(), const ExpansionTileThemeData().copyWith());
|
||||||
|
expect(const ExpansionTileThemeData().hashCode, const ExpansionTileThemeData().copyWith().hashCode);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('ExpansionTileThemeData defaults', () {
|
||||||
|
const ExpansionTileThemeData theme = ExpansionTileThemeData();
|
||||||
|
expect(theme.backgroundColor, null);
|
||||||
|
expect(theme.collapsedBackgroundColor, null);
|
||||||
|
expect(theme.tilePadding, null);
|
||||||
|
expect(theme.expandedAlignment, null);
|
||||||
|
expect(theme.childrenPadding, null);
|
||||||
|
expect(theme.iconColor, null);
|
||||||
|
expect(theme.collapsedIconColor, null);
|
||||||
|
expect(theme.textColor, null);
|
||||||
|
expect(theme.collapsedTextColor, null);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('Default ExpansionTileThemeData debugFillProperties', (WidgetTester tester) async {
|
||||||
|
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
||||||
|
const TooltipThemeData().debugFillProperties(builder);
|
||||||
|
|
||||||
|
final List<String> description = builder.properties
|
||||||
|
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
|
||||||
|
.map((DiagnosticsNode node) => node.toString())
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
expect(description, <String>[]);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('ExpansionTileThemeData implements debugFillProperties', (WidgetTester tester) async {
|
||||||
|
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
||||||
|
const ExpansionTileThemeData(
|
||||||
|
backgroundColor: Color(0xff000000),
|
||||||
|
collapsedBackgroundColor: Color(0xff6f83fc),
|
||||||
|
tilePadding: EdgeInsets.all(20.0),
|
||||||
|
expandedAlignment: Alignment.bottomCenter,
|
||||||
|
childrenPadding: EdgeInsets.all(10.0),
|
||||||
|
iconColor: Color(0xffa7c61c),
|
||||||
|
collapsedIconColor: Color(0xffdd0b1f),
|
||||||
|
textColor: Color(0xffffffff),
|
||||||
|
collapsedTextColor: Color(0xff522bab),
|
||||||
|
).debugFillProperties(builder);
|
||||||
|
|
||||||
|
final List<String> description = builder.properties
|
||||||
|
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
|
||||||
|
.map((DiagnosticsNode node) => node.toString())
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
expect(description, <String>[
|
||||||
|
'backgroundColor: Color(0xff000000)',
|
||||||
|
'collapsedBackgroundColor: Color(0xff6f83fc)',
|
||||||
|
'tilePadding: EdgeInsets.all(20.0)',
|
||||||
|
'expandedAlignment: Alignment.bottomCenter',
|
||||||
|
'childrenPadding: EdgeInsets.all(10.0)',
|
||||||
|
'iconColor: Color(0xffa7c61c)',
|
||||||
|
'collapsedIconColor: Color(0xffdd0b1f)',
|
||||||
|
'textColor: Color(0xffffffff)',
|
||||||
|
'collapsedTextColor: Color(0xff522bab)',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('ExpansionTileTheme - collapsed', (WidgetTester tester) async {
|
||||||
|
final Key tileKey = UniqueKey();
|
||||||
|
final Key titleKey = UniqueKey();
|
||||||
|
final Key iconKey = UniqueKey();
|
||||||
|
const Color backgroundColor = Colors.orange;
|
||||||
|
const Color collapsedBackgroundColor = Colors.red;
|
||||||
|
const Color iconColor = Colors.green;
|
||||||
|
const Color collapsedIconColor = Colors.blue;
|
||||||
|
const Color textColor = Colors.black;
|
||||||
|
const Color collapsedTextColor = Colors.white;
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
theme: ThemeData(
|
||||||
|
expansionTileTheme: const ExpansionTileThemeData(
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
collapsedBackgroundColor: collapsedBackgroundColor,
|
||||||
|
tilePadding: EdgeInsets.fromLTRB(8, 12, 4, 10),
|
||||||
|
expandedAlignment: Alignment.centerRight,
|
||||||
|
childrenPadding: EdgeInsets.all(20.0),
|
||||||
|
iconColor: iconColor,
|
||||||
|
collapsedIconColor: collapsedIconColor,
|
||||||
|
textColor: textColor,
|
||||||
|
collapsedTextColor: collapsedTextColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
home: Material(
|
||||||
|
child: Center(
|
||||||
|
child: ExpansionTile(
|
||||||
|
key: tileKey,
|
||||||
|
title: TestText('Collapsed Tile', key: titleKey),
|
||||||
|
trailing: TestIcon(key: iconKey),
|
||||||
|
children: const <Widget>[Text('Tile 1')],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final BoxDecoration boxDecoration = tester.firstWidget<Container>(find.descendant(
|
||||||
|
of: find.byKey(tileKey),
|
||||||
|
matching: find.byType(Container),
|
||||||
|
)).decoration! as BoxDecoration;
|
||||||
|
// Check the tile's collapsed background color when collapsedBackgroundColor is applied.
|
||||||
|
expect(boxDecoration.color, collapsedBackgroundColor);
|
||||||
|
|
||||||
|
final Rect titleRect = tester.getRect(find.text('Collapsed Tile'));
|
||||||
|
final Rect trailingRect = tester.getRect(find.byIcon(Icons.expand_more));
|
||||||
|
final Rect listTileRect = tester.getRect(find.byType(ListTile));
|
||||||
|
final Rect tallerWidget = titleRect.height > trailingRect.height ? titleRect : trailingRect;
|
||||||
|
|
||||||
|
// Check the positions of title and trailing Widgets, after padding is applied.
|
||||||
|
expect(listTileRect.left, titleRect.left - 8);
|
||||||
|
expect(listTileRect.right, trailingRect.right + 4);
|
||||||
|
|
||||||
|
// Calculate the remaining height of ListTile from the default height.
|
||||||
|
final double remainingHeight = 56 - tallerWidget.height;
|
||||||
|
expect(listTileRect.top, tallerWidget.top - remainingHeight / 2 - 12);
|
||||||
|
expect(listTileRect.bottom, tallerWidget.bottom + remainingHeight / 2 + 10);
|
||||||
|
|
||||||
|
Color getIconColor() => tester.state<TestIconState>(find.byType(TestIcon)).iconTheme.color!;
|
||||||
|
Color getTextColor() => tester.state<TestTextState>(find.byType(TestText)).textStyle.color!;
|
||||||
|
|
||||||
|
// Check the collapsed icon color when iconColor is applied.
|
||||||
|
expect(getIconColor(), collapsedIconColor);
|
||||||
|
// Check the collapsed text color when textColor is applied.
|
||||||
|
expect(getTextColor(), collapsedTextColor);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('ExpansionTileTheme - expanded', (WidgetTester tester) async {
|
||||||
|
final Key tileKey = UniqueKey();
|
||||||
|
final Key titleKey = UniqueKey();
|
||||||
|
final Key iconKey = UniqueKey();
|
||||||
|
const Color backgroundColor = Colors.orange;
|
||||||
|
const Color collapsedBackgroundColor = Colors.red;
|
||||||
|
const Color iconColor = Colors.green;
|
||||||
|
const Color collapsedIconColor = Colors.blue;
|
||||||
|
const Color textColor = Colors.black;
|
||||||
|
const Color collapsedTextColor = Colors.white;
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
theme: ThemeData(
|
||||||
|
expansionTileTheme: const ExpansionTileThemeData(
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
collapsedBackgroundColor: collapsedBackgroundColor,
|
||||||
|
tilePadding: EdgeInsets.fromLTRB(8, 12, 4, 10),
|
||||||
|
expandedAlignment: Alignment.centerRight,
|
||||||
|
childrenPadding: EdgeInsets.all(20.0),
|
||||||
|
iconColor: iconColor,
|
||||||
|
collapsedIconColor: collapsedIconColor,
|
||||||
|
textColor: textColor,
|
||||||
|
collapsedTextColor: collapsedTextColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
home: Material(
|
||||||
|
child: Center(
|
||||||
|
child: ExpansionTile(
|
||||||
|
key: tileKey,
|
||||||
|
initiallyExpanded: true,
|
||||||
|
title: TestText('Expanded Tile', key: titleKey),
|
||||||
|
trailing: TestIcon(key: iconKey),
|
||||||
|
children: const <Widget>[Text('Tile 1')],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
final BoxDecoration boxDecoration = tester.firstWidget<Container>(find.descendant(
|
||||||
|
of: find.byKey(tileKey),
|
||||||
|
matching: find.byType(Container),
|
||||||
|
)).decoration! as BoxDecoration;
|
||||||
|
// Check the tile's background color when backgroundColor is applied.
|
||||||
|
expect(boxDecoration.color, backgroundColor);
|
||||||
|
|
||||||
|
final Rect titleRect = tester.getRect(find.text('Expanded Tile'));
|
||||||
|
final Rect trailingRect = tester.getRect(find.byIcon(Icons.expand_more));
|
||||||
|
final Rect listTileRect = tester.getRect(find.byType(ListTile));
|
||||||
|
final Rect tallerWidget = titleRect.height > trailingRect.height ? titleRect : trailingRect;
|
||||||
|
|
||||||
|
// Check the positions of title and trailing Widgets, after padding is applied.
|
||||||
|
expect(listTileRect.left, titleRect.left - 8);
|
||||||
|
expect(listTileRect.right, trailingRect.right + 4);
|
||||||
|
|
||||||
|
// Calculate the remaining height of ListTile from the default height.
|
||||||
|
final double remainingHeight = 56 - tallerWidget.height;
|
||||||
|
expect(listTileRect.top, tallerWidget.top - remainingHeight / 2 - 12);
|
||||||
|
expect(listTileRect.bottom, tallerWidget.bottom + remainingHeight / 2 + 10);
|
||||||
|
|
||||||
|
Color getIconColor() => tester.state<TestIconState>(find.byType(TestIcon)).iconTheme.color!;
|
||||||
|
Color getTextColor() => tester.state<TestTextState>(find.byType(TestText)).textStyle.color!;
|
||||||
|
|
||||||
|
// Check the expanded icon color when iconColor is applied.
|
||||||
|
expect(getIconColor(), iconColor);
|
||||||
|
// Check the expanded text color when textColor is applied.
|
||||||
|
expect(getTextColor(), textColor);
|
||||||
|
|
||||||
|
// Check the child position when expandedAlignment is applied.
|
||||||
|
final Rect childRect = tester.getRect(find.text('Tile 1'));
|
||||||
|
expect(childRect.right, 800 - 20);
|
||||||
|
expect(childRect.left, 800 - childRect.width - 20);
|
||||||
|
|
||||||
|
// Check the child padding when childrenPadding is applied.
|
||||||
|
final Rect paddingRect = tester.getRect(find.byType(Padding).last);
|
||||||
|
expect(childRect.top, paddingRect.top + 20);
|
||||||
|
expect(childRect.left, paddingRect.left + 20);
|
||||||
|
expect(childRect.right, paddingRect.right - 20);
|
||||||
|
expect(childRect.bottom, paddingRect.bottom - 20);
|
||||||
|
});
|
||||||
|
}
|
@ -430,6 +430,7 @@ void main() {
|
|||||||
sliderTheme: sliderTheme,
|
sliderTheme: sliderTheme,
|
||||||
tabBarTheme: const TabBarTheme(labelColor: Colors.black),
|
tabBarTheme: const TabBarTheme(labelColor: Colors.black),
|
||||||
tooltipTheme: const TooltipThemeData(height: 100),
|
tooltipTheme: const TooltipThemeData(height: 100),
|
||||||
|
expansionTileTheme: const ExpansionTileThemeData(backgroundColor: Colors.black),
|
||||||
cardTheme: const CardTheme(color: Colors.black),
|
cardTheme: const CardTheme(color: Colors.black),
|
||||||
chipTheme: chipTheme,
|
chipTheme: chipTheme,
|
||||||
platform: TargetPlatform.iOS,
|
platform: TargetPlatform.iOS,
|
||||||
@ -529,6 +530,7 @@ void main() {
|
|||||||
sliderTheme: otherSliderTheme,
|
sliderTheme: otherSliderTheme,
|
||||||
tabBarTheme: const TabBarTheme(labelColor: Colors.white),
|
tabBarTheme: const TabBarTheme(labelColor: Colors.white),
|
||||||
tooltipTheme: const TooltipThemeData(height: 100),
|
tooltipTheme: const TooltipThemeData(height: 100),
|
||||||
|
expansionTileTheme: const ExpansionTileThemeData(backgroundColor: Colors.black),
|
||||||
cardTheme: const CardTheme(color: Colors.white),
|
cardTheme: const CardTheme(color: Colors.white),
|
||||||
chipTheme: otherChipTheme,
|
chipTheme: otherChipTheme,
|
||||||
platform: TargetPlatform.android,
|
platform: TargetPlatform.android,
|
||||||
@ -841,6 +843,7 @@ void main() {
|
|||||||
'timePickerTheme',
|
'timePickerTheme',
|
||||||
'toggleButtonsTheme',
|
'toggleButtonsTheme',
|
||||||
'tooltipTheme',
|
'tooltipTheme',
|
||||||
|
'expansionTileTheme',
|
||||||
// DEPRECATED (newest deprecations at the bottom)
|
// DEPRECATED (newest deprecations at the bottom)
|
||||||
'useTextSelectionTheme',
|
'useTextSelectionTheme',
|
||||||
'textSelectionColor',
|
'textSelectionColor',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user