Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
e8eac0d0
Unverified
Commit
e8eac0d0
authored
Feb 07, 2023
by
Taha Tesser
Committed by
GitHub
Feb 07, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update `ExpansionTile` to support Material 3 & add an example (#119712)
parent
da36bd6f
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
228 additions
and
23 deletions
+228
-23
gen_defaults.dart
dev/tools/gen_defaults/bin/gen_defaults.dart
+2
-0
expansion_tile_template.dart
dev/tools/gen_defaults/lib/expansion_tile_template.dart
+34
-0
expansion_tile.0.dart
...les/api/lib/material/expansion_tile/expansion_tile.0.dart
+13
-13
expansion_tile.0_test.dart
...i/test/material/expansion_tile/expansion_tile.0_test.dart
+40
-0
expansion_tile.dart
packages/flutter/lib/src/material/expansion_tile.dart
+76
-10
expansion_tile_test.dart
packages/flutter/test/material/expansion_tile_test.dart
+63
-0
No files found.
dev/tools/gen_defaults/bin/gen_defaults.dart
View file @
e8eac0d0
...
...
@@ -31,6 +31,7 @@ import 'package:gen_defaults/date_picker_template.dart';
import
'package:gen_defaults/dialog_template.dart'
;
import
'package:gen_defaults/divider_template.dart'
;
import
'package:gen_defaults/drawer_template.dart'
;
import
'package:gen_defaults/expansion_tile_template.dart'
;
import
'package:gen_defaults/fab_template.dart'
;
import
'package:gen_defaults/filter_chip_template.dart'
;
import
'package:gen_defaults/icon_button_template.dart'
;
...
...
@@ -153,6 +154,7 @@ Future<void> main(List<String> args) async {
DialogTemplate
(
'Dialog'
,
'
$materialLib
/dialog.dart'
,
tokens
).
updateFile
();
DividerTemplate
(
'Divider'
,
'
$materialLib
/divider.dart'
,
tokens
).
updateFile
();
DrawerTemplate
(
'Drawer'
,
'
$materialLib
/drawer.dart'
,
tokens
).
updateFile
();
ExpansionTileTemplate
(
'ExpansionTile'
,
'
$materialLib
/expansion_tile.dart'
,
tokens
).
updateFile
();
FABTemplate
(
'FAB'
,
'
$materialLib
/floating_action_button.dart'
,
tokens
).
updateFile
();
FilterChipTemplate
(
'ChoiceChip'
,
'
$materialLib
/choice_chip.dart'
,
tokens
).
updateFile
();
FilterChipTemplate
(
'FilterChip'
,
'
$materialLib
/filter_chip.dart'
,
tokens
).
updateFile
();
...
...
dev/tools/gen_defaults/lib/expansion_tile_template.dart
0 → 100644
View file @
e8eac0d0
// 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
'template.dart'
;
class
ExpansionTileTemplate
extends
TokenTemplate
{
const
ExpansionTileTemplate
(
super
.
blockName
,
super
.
fileName
,
super
.
tokens
,
{
super
.
colorSchemePrefix
=
'_colors.'
,
});
@override
String
generate
()
=>
'''
class _
${blockName}
DefaultsM3 extends ExpansionTileThemeData {
_
${blockName}
DefaultsM3(this.context);
final BuildContext context;
late final ThemeData _theme = Theme.of(context);
late final ColorScheme _colors = _theme.colorScheme;
@override
Color? get textColor =>
${textStyle("md.comp.list.list-item.label-text")}
!.color;
@override
Color? get iconColor =>
${componentColor('md.comp.list.list-item.selected.trailing-icon')}
;
@override
Color? get collapsedTextColor =>
${textStyle("md.comp.list.list-item.label-text")}
!.color;
@override
Color? get collapsedIconColor =>
${componentColor('md.comp.list.list-item.unselected.trailing-icon')}
;
}
'''
;
}
examples/api/lib/material/expansion_tile/expansion_tile.0.dart
View file @
e8eac0d0
...
...
@@ -6,33 +6,31 @@
import
'package:flutter/material.dart'
;
void
main
(
)
=>
runApp
(
const
My
App
());
void
main
(
)
=>
runApp
(
const
ExpansionTile
App
());
class
MyApp
extends
StatelessWidget
{
const
MyApp
({
super
.
key
});
static
const
String
_title
=
'Flutter Code Sample'
;
class
ExpansionTileApp
extends
StatelessWidget
{
const
ExpansionTileApp
({
super
.
key
});
@override
Widget
build
(
BuildContext
context
)
{
return
MaterialApp
(
t
itle:
_title
,
t
heme:
ThemeData
(
useMaterial3:
true
)
,
home:
Scaffold
(
appBar:
AppBar
(
title:
const
Text
(
_title
)),
body:
const
MyStatefulWidget
(),
appBar:
AppBar
(
title:
const
Text
(
'ExpansionTile Sample'
)),
body:
const
ExpansionTileExample
(),
),
);
}
}
class
MyStatefulWidget
extends
StatefulWidget
{
const
MyStatefulWidget
({
super
.
key
});
class
ExpansionTileExample
extends
StatefulWidget
{
const
ExpansionTileExample
({
super
.
key
});
@override
State
<
MyStatefulWidget
>
createState
()
=>
_MyStatefulWidget
State
();
State
<
ExpansionTileExample
>
createState
()
=>
_ExpansionTileExample
State
();
}
class
_
MyStatefulWidgetState
extends
State
<
MyStatefulWidget
>
{
class
_
ExpansionTileExampleState
extends
State
<
ExpansionTileExample
>
{
bool
_customTileExpanded
=
false
;
@override
...
...
@@ -58,7 +56,9 @@ class _MyStatefulWidgetState extends State<MyStatefulWidget> {
ListTile
(
title:
Text
(
'This is tile number 2'
)),
],
onExpansionChanged:
(
bool
expanded
)
{
setState
(()
=>
_customTileExpanded
=
expanded
);
setState
(()
{
_customTileExpanded
=
expanded
;
});
},
),
const
ExpansionTile
(
...
...
examples/api/test/material/expansion_tile/expansion_tile.0_test.dart
0 → 100644
View file @
e8eac0d0
// 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_api_samples/material/expansion_tile/expansion_tile.0.dart'
as
example
;
import
'package:flutter_test/flutter_test.dart'
;
void
main
(
)
{
testWidgets
(
'When expansion tiles are expanded tile numbers are revealed'
,
(
WidgetTester
tester
)
async
{
const
int
totalTiles
=
3
;
await
tester
.
pumpWidget
(
const
example
.
ExpansionTileApp
(),
);
expect
(
find
.
byType
(
ExpansionTile
),
findsNWidgets
(
totalTiles
));
const
String
tileOne
=
'This is tile number 1'
;
expect
(
find
.
text
(
tileOne
),
findsNothing
);
await
tester
.
tap
(
find
.
text
(
'ExpansionTile 1'
));
await
tester
.
pumpAndSettle
();
expect
(
find
.
text
(
tileOne
),
findsOneWidget
);
const
String
tileTwo
=
'This is tile number 2'
;
expect
(
find
.
text
(
tileTwo
),
findsNothing
);
await
tester
.
tap
(
find
.
text
(
'ExpansionTile 2'
));
await
tester
.
pumpAndSettle
();
expect
(
find
.
text
(
tileTwo
),
findsOneWidget
);
const
String
tileThree
=
'This is tile number 3'
;
expect
(
find
.
text
(
tileThree
),
findsNothing
);
await
tester
.
tap
(
find
.
text
(
'ExpansionTile 3'
));
await
tester
.
pumpAndSettle
();
expect
(
find
.
text
(
tileThree
),
findsOneWidget
);
});
}
packages/flutter/lib/src/material/expansion_tile.dart
View file @
e8eac0d0
...
...
@@ -34,7 +34,8 @@ const Duration _kExpand = Duration(milliseconds: 200);
/// to the [leading] and [trailing] properties of [ExpansionTile].
///
/// {@tool dartpad}
/// This example demonstrates different configurations of ExpansionTile.
/// This example demonstrates how the [ExpansionTile] icon's location and appearance
/// can be customized.
///
/// ** See code in examples/api/lib/material/expansion_tile/expansion_tile.0.dart **
/// {@end-tool}
...
...
@@ -216,7 +217,7 @@ class ExpansionTile extends StatefulWidget {
/// 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.
/// is also null then the value of [
ColorScheme.primary
] is used.
///
/// See also:
///
...
...
@@ -227,6 +228,15 @@ class ExpansionTile extends StatefulWidget {
/// The icon color of tile's expansion arrow icon when the sublist is collapsed.
///
/// Used to override to the [ListTileThemeData.iconColor].
///
/// If this property is null then [ExpansionTileThemeData.collapsedIconColor] is used. If that
/// is also null and [ThemeData.useMaterial3] is true, [ColorScheme.onSurface] is used. Otherwise,
/// defaults to [ThemeData.unselectedWidgetColor] color.
///
/// See also:
///
/// * [ExpansionTileTheme.of], which returns the nearest [ExpansionTileTheme]'s
/// [ExpansionTileThemeData].
final
Color
?
collapsedIconColor
;
...
...
@@ -235,7 +245,8 @@ class ExpansionTile extends StatefulWidget {
/// 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.
/// is also null then and [ThemeData.useMaterial3] is true, color of the [TextTheme.bodyLarge]
/// will be used for the [title] and [subtitle]. Otherwise, defaults to [ColorScheme.primary] color.
///
/// See also:
///
...
...
@@ -247,8 +258,10 @@ class ExpansionTile extends StatefulWidget {
///
/// 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.
/// If this property is null then [ExpansionTileThemeData.collapsedTextColor] is used.
/// If that is also null and [ThemeData.useMaterial3] is true, color of the
/// [TextTheme.bodyLarge] will be used for the [title] and [subtitle]. Otherwise,
/// defaults to color of the [TextTheme.titleMedium].
///
/// See also:
///
...
...
@@ -441,7 +454,9 @@ class _ExpansionTileState extends State<ExpansionTile> with SingleTickerProvider
void
didChangeDependencies
()
{
final
ThemeData
theme
=
Theme
.
of
(
context
);
final
ExpansionTileThemeData
expansionTileTheme
=
ExpansionTileTheme
.
of
(
context
);
final
ColorScheme
colorScheme
=
theme
.
colorScheme
;
final
ExpansionTileThemeData
defaults
=
theme
.
useMaterial3
?
_ExpansionTileDefaultsM3
(
context
)
:
_ExpansionTileDefaultsM2
(
context
);
_borderTween
..
begin
=
widget
.
collapsedShape
??
expansionTileTheme
.
collapsedShape
...
...
@@ -458,13 +473,13 @@ class _ExpansionTileState extends State<ExpansionTile> with SingleTickerProvider
_headerColorTween
..
begin
=
widget
.
collapsedTextColor
??
expansionTileTheme
.
collapsedTextColor
??
theme
.
textTheme
.
titleMedium
!.
c
olor
..
end
=
widget
.
textColor
??
expansionTileTheme
.
textColor
??
colorScheme
.
primary
;
??
defaults
.
collapsedTextC
olor
..
end
=
widget
.
textColor
??
expansionTileTheme
.
textColor
??
defaults
.
textColor
;
_iconColorTween
..
begin
=
widget
.
collapsedIconColor
??
expansionTileTheme
.
collapsedIconColor
??
theme
.
unselectedWidget
Color
..
end
=
widget
.
iconColor
??
expansionTileTheme
.
iconColor
??
colorScheme
.
primary
;
??
defaults
.
collapsedIcon
Color
..
end
=
widget
.
iconColor
??
expansionTileTheme
.
iconColor
??
defaults
.
iconColor
;
_backgroundColorTween
..
begin
=
widget
.
collapsedBackgroundColor
??
expansionTileTheme
.
collapsedBackgroundColor
..
end
=
widget
.
backgroundColor
??
expansionTileTheme
.
backgroundColor
;
...
...
@@ -498,3 +513,54 @@ class _ExpansionTileState extends State<ExpansionTile> with SingleTickerProvider
);
}
}
class
_ExpansionTileDefaultsM2
extends
ExpansionTileThemeData
{
_ExpansionTileDefaultsM2
(
this
.
context
);
final
BuildContext
context
;
late
final
ThemeData
_theme
=
Theme
.
of
(
context
);
late
final
ColorScheme
_colorScheme
=
_theme
.
colorScheme
;
@override
Color
?
get
textColor
=>
_colorScheme
.
primary
;
@override
Color
?
get
iconColor
=>
_colorScheme
.
primary
;
@override
Color
?
get
collapsedTextColor
=>
_theme
.
textTheme
.
titleMedium
!.
color
;
@override
Color
?
get
collapsedIconColor
=>
_theme
.
unselectedWidgetColor
;
}
// BEGIN GENERATED TOKEN PROPERTIES - ExpansionTile
// Do not edit by hand. The code between the "BEGIN GENERATED" and
// "END GENERATED" comments are generated from data in the Material
// Design token database by the script:
// dev/tools/gen_defaults/bin/gen_defaults.dart.
// Token database version: v0_152
class
_ExpansionTileDefaultsM3
extends
ExpansionTileThemeData
{
_ExpansionTileDefaultsM3
(
this
.
context
);
final
BuildContext
context
;
late
final
ThemeData
_theme
=
Theme
.
of
(
context
);
late
final
ColorScheme
_colors
=
_theme
.
colorScheme
;
@override
Color
?
get
textColor
=>
Theme
.
of
(
context
).
textTheme
.
bodyLarge
!.
color
;
@override
Color
?
get
iconColor
=>
_colors
.
primary
;
@override
Color
?
get
collapsedTextColor
=>
Theme
.
of
(
context
).
textTheme
.
bodyLarge
!.
color
;
@override
Color
?
get
collapsedIconColor
=>
_colors
.
onSurface
;
}
// END GENERATED TOKEN PROPERTIES - ExpansionTile
packages/flutter/test/material/expansion_tile_test.dart
View file @
e8eac0d0
...
...
@@ -522,6 +522,35 @@ void main() {
expect
(
shapeDecoration
.
color
,
backgroundColor
);
});
testWidgets
(
'ExpansionTile default iconColor, textColor'
,
(
WidgetTester
tester
)
async
{
final
ThemeData
theme
=
ThemeData
(
useMaterial3:
true
);
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
theme
,
home:
const
Material
(
child:
ExpansionTile
(
title:
TestText
(
'title'
),
trailing:
TestIcon
(),
children:
<
Widget
>[
SizedBox
(
height:
100
,
width:
100
),
],
),
),
));
Color
getIconColor
()
=>
tester
.
state
<
TestIconState
>(
find
.
byType
(
TestIcon
)).
iconTheme
.
color
!;
Color
getTextColor
()
=>
tester
.
state
<
TestTextState
>(
find
.
byType
(
TestText
)).
textStyle
.
color
!;
expect
(
getIconColor
(),
theme
.
colorScheme
.
onSurface
);
expect
(
getTextColor
(),
theme
.
textTheme
.
bodyLarge
!.
color
);
await
tester
.
tap
(
find
.
text
(
'title'
));
await
tester
.
pumpAndSettle
();
expect
(
getIconColor
(),
theme
.
colorScheme
.
primary
);
expect
(
getTextColor
(),
theme
.
textTheme
.
bodyLarge
!.
color
);
});
testWidgets
(
'ExpansionTile iconColor, textColor'
,
(
WidgetTester
tester
)
async
{
// Regression test for https://github.com/flutter/flutter/pull/78281
...
...
@@ -666,4 +695,38 @@ void main() {
expect
(
listTile
.
leading
.
runtimeType
,
Icon
);
expect
(
listTile
.
trailing
,
isNull
);
});
group
(
'Material 2'
,
()
{
// Tests that are only relevant for Material 2. Once ThemeData.useMaterial3
// is turned on by default, these tests can be removed.
testWidgets
(
'ExpansionTile default iconColor, textColor'
,
(
WidgetTester
tester
)
async
{
final
ThemeData
theme
=
ThemeData
(
useMaterial3:
false
);
await
tester
.
pumpWidget
(
MaterialApp
(
theme:
theme
,
home:
const
Material
(
child:
ExpansionTile
(
title:
TestText
(
'title'
),
trailing:
TestIcon
(),
children:
<
Widget
>[
SizedBox
(
height:
100
,
width:
100
),
],
),
),
));
Color
getIconColor
()
=>
tester
.
state
<
TestIconState
>(
find
.
byType
(
TestIcon
)).
iconTheme
.
color
!;
Color
getTextColor
()
=>
tester
.
state
<
TestTextState
>(
find
.
byType
(
TestText
)).
textStyle
.
color
!;
expect
(
getIconColor
(),
theme
.
unselectedWidgetColor
);
expect
(
getTextColor
(),
theme
.
textTheme
.
titleMedium
!.
color
);
await
tester
.
tap
(
find
.
text
(
'title'
));
await
tester
.
pumpAndSettle
();
expect
(
getIconColor
(),
theme
.
colorScheme
.
primary
);
expect
(
getTextColor
(),
theme
.
colorScheme
.
primary
);
});
});
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment