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
ae976665
Unverified
Commit
ae976665
authored
Jun 09, 2021
by
J-P Nurmi
Committed by
GitHub
Jun 09, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add ExpansionTile.controlAffinity (#80360)
parent
e467018d
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
163 additions
and
12 deletions
+163
-12
expansion_tile.dart
packages/flutter/lib/src/material/expansion_tile.dart
+101
-12
list_tile.dart
packages/flutter/lib/src/material/list_tile.dart
+2
-0
expansion_tile_test.dart
packages/flutter/test/material/expansion_tile_test.dart
+60
-0
No files found.
packages/flutter/lib/src/material/expansion_tile.dart
View file @
ae976665
...
...
@@ -12,7 +12,7 @@ import 'theme.dart';
const
Duration
_kExpand
=
Duration
(
milliseconds:
200
);
/// A single-line [ListTile] with a
trailing butt
on that expands or collapses
/// A single-line [ListTile] with a
n expansion arrow ic
on that expands or collapses
/// the tile to reveal or hide the [children].
///
/// This widget is typically used with [ListView] to create an
...
...
@@ -26,6 +26,57 @@ const Duration _kExpand = Duration(milliseconds: 200);
/// the tile is expanded and collapsed: between [iconColor], [collapsedIconColor] and
/// between [textColor] and [collapsedTextColor].
///
/// The expansion arrow icon is shown on the right by default in left-to-right languages
/// (i.e. the trailing edge). This can be changed using [controlAffinity]. This maps
/// to the [leading] and [trailing] properties of [ExpansionTile].
///
/// {@tool dartpad --template=stateful_widget_scaffold}
///
/// This example demonstrates different configurations of ExpansionTile.
///
/// ```dart
/// bool _customTileExpanded = false;
///
/// @override
/// Widget build(BuildContext context) {
/// return Column(
/// children: <Widget>[
/// const ExpansionTile(
/// title: Text('ExpansionTile 1'),
/// subtitle: Text('Trailing expansion arrow icon'),
/// children: <Widget>[
/// ListTile(title: Text('This is tile number 1')),
/// ],
/// ),
/// ExpansionTile(
/// title: const Text('ExpansionTile 2'),
/// subtitle: const Text('Custom expansion arrow icon'),
/// trailing: Icon(
/// _customTileExpanded
/// ? Icons.arrow_drop_down_circle
/// : Icons.arrow_drop_down,
/// ),
/// children: const <Widget>[
/// ListTile(title: Text('This is tile number 2')),
/// ],
/// onExpansionChanged: (bool expanded) {
/// setState(() => _customTileExpanded = expanded);
/// },
/// ),
/// const ExpansionTile(
/// title: Text('ExpansionTile 3'),
/// subtitle: Text('Leading expansion arrow icon'),
/// controlAffinity: ListTileControlAffinity.leading,
/// children: <Widget>[
/// ListTile(title: Text('This is tile number 3')),
/// ],
/// ),
/// ],
/// );
/// }
/// ```
/// {@end-tool}
///
/// See also:
///
/// * [ListTile], useful for creating expansion tile [children] when the
...
...
@@ -33,7 +84,7 @@ const Duration _kExpand = Duration(milliseconds: 200);
/// * The "Expand and collapse" section of
/// <https://material.io/components/lists#types>
class
ExpansionTile
extends
StatefulWidget
{
/// Creates a single-line [ListTile] with a
trailing butt
on that expands or collapses
/// Creates a single-line [ListTile] with a
n expansion arrow ic
on that expands or collapses
/// the tile to reveal or hide the [children]. The [initiallyExpanded] property must
/// be non-null.
const
ExpansionTile
({
...
...
@@ -56,6 +107,7 @@ class ExpansionTile extends StatefulWidget {
this
.
collapsedTextColor
,
this
.
iconColor
,
this
.
collapsedIconColor
,
this
.
controlAffinity
,
})
:
assert
(
initiallyExpanded
!=
null
),
assert
(
maintainState
!=
null
),
assert
(
...
...
@@ -68,6 +120,9 @@ class ExpansionTile extends StatefulWidget {
/// A widget to display before the title.
///
/// Typically a [CircleAvatar] widget.
///
/// Note that depending on the value of [controlAffinity], the [leading] widget
/// may replace the rotating expansion arrow icon.
final
Widget
?
leading
;
/// The primary content of the list item.
...
...
@@ -98,7 +153,10 @@ class ExpansionTile extends StatefulWidget {
/// When not null, defines the background color of tile when the sublist is collapsed.
final
Color
?
collapsedBackgroundColor
;
/// A widget to display instead of a rotating arrow icon.
/// A widget to display after the title.
///
/// Note that depending on the value of [controlAffinity], the [trailing] widget
/// may replace the rotating expansion arrow icon.
final
Widget
?
trailing
;
/// Specifies if the list tile is initially expanded (true) or collapsed (false, the default).
...
...
@@ -157,14 +215,12 @@ class ExpansionTile extends StatefulWidget {
/// When the value is null, the value of `childrenPadding` is [EdgeInsets.zero].
final
EdgeInsetsGeometry
?
childrenPadding
;
/// The icon color of tile's [trailing] expansion 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 [ListTileTheme.iconColor].
final
Color
?
iconColor
;
/// The icon color of tile's [trailing] expansion icon when the
/// sublist is collapsed.
/// The icon color of tile's expansion arrow icon when the sublist is collapsed.
///
/// Used to override to the [ListTileTheme.iconColor].
final
Color
?
collapsedIconColor
;
...
...
@@ -180,6 +236,12 @@ class ExpansionTile extends StatefulWidget {
/// Used to override to the [ListTileTheme.textColor].
final
Color
?
collapsedTextColor
;
/// Typically used to force the expansion arrow icon to the tile's leading or trailing edge.
///
/// By default, the value of `controlAffinity` is [ListTileControlAffinity.platform],
/// which means that the expansion arrow icon will appear on the tile's trailing edge.
final
ListTileControlAffinity
?
controlAffinity
;
@override
State
<
ExpansionTile
>
createState
()
=>
_ExpansionTileState
();
}
...
...
@@ -245,6 +307,36 @@ class _ExpansionTileState extends State<ExpansionTile> with SingleTickerProvider
widget
.
onExpansionChanged
?.
call
(
_isExpanded
);
}
// Platform or null affinity defaults to trailing.
ListTileControlAffinity
_effectiveAffinity
(
ListTileControlAffinity
?
affinity
)
{
switch
(
affinity
??
ListTileControlAffinity
.
trailing
)
{
case
ListTileControlAffinity
.
leading
:
return
ListTileControlAffinity
.
leading
;
case
ListTileControlAffinity
.
trailing
:
case
ListTileControlAffinity
.
platform
:
return
ListTileControlAffinity
.
trailing
;
}
}
Widget
?
_buildIcon
(
BuildContext
context
)
{
return
RotationTransition
(
turns:
_iconTurns
,
child:
const
Icon
(
Icons
.
expand_more
),
);
}
Widget
?
_buildLeadingIcon
(
BuildContext
context
)
{
if
(
_effectiveAffinity
(
widget
.
controlAffinity
)
!=
ListTileControlAffinity
.
leading
)
return
null
;
return
_buildIcon
(
context
);
}
Widget
?
_buildTrailingIcon
(
BuildContext
context
)
{
if
(
_effectiveAffinity
(
widget
.
controlAffinity
)
!=
ListTileControlAffinity
.
trailing
)
return
null
;
return
_buildIcon
(
context
);
}
Widget
_buildChildren
(
BuildContext
context
,
Widget
?
child
)
{
final
Color
borderSideColor
=
_borderColor
.
value
??
Colors
.
transparent
;
...
...
@@ -265,13 +357,10 @@ class _ExpansionTileState extends State<ExpansionTile> with SingleTickerProvider
child:
ListTile
(
onTap:
_handleTap
,
contentPadding:
widget
.
tilePadding
,
leading:
widget
.
leading
,
leading:
widget
.
leading
??
_buildLeadingIcon
(
context
)
,
title:
widget
.
title
,
subtitle:
widget
.
subtitle
,
trailing:
widget
.
trailing
??
RotationTransition
(
turns:
_iconTurns
,
child:
const
Icon
(
Icons
.
expand_more
),
),
trailing:
widget
.
trailing
??
_buildTrailingIcon
(
context
),
),
),
ClipRect
(
...
...
packages/flutter/lib/src/material/list_tile.dart
View file @
ae976665
...
...
@@ -221,6 +221,8 @@ class ListTileTheme extends InheritedTheme {
/// * [CheckboxListTile], which combines a [ListTile] with a [Checkbox].
/// * [RadioListTile], which combines a [ListTile] with a [Radio] button.
/// * [SwitchListTile], which combines a [ListTile] with a [Switch].
/// * [ExpansionTile], which combines a [ListTile] with a button that expands
/// or collapses the tile to reveal or hide the children.
enum
ListTileControlAffinity
{
/// Position the control on the leading edge, and the secondary widget, if
/// any, on the trailing edge.
...
...
packages/flutter/test/material/expansion_tile_test.dart
View file @
ae976665
...
...
@@ -560,4 +560,64 @@ void main() {
expect
(
getIconColor
(),
iconColor
);
expect
(
getTextColor
(),
textColor
);
});
testWidgets
(
'ExpansionTile platform controlAffinity test'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
const
MaterialApp
(
home:
Material
(
child:
ExpansionTile
(
title:
Text
(
'Title'
),
),
),
));
final
ListTile
listTile
=
tester
.
widget
(
find
.
byType
(
ListTile
));
expect
(
listTile
.
leading
,
isNull
);
expect
(
listTile
.
trailing
.
runtimeType
,
RotationTransition
);
});
testWidgets
(
'ExpansionTile trailing controlAffinity test'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
const
MaterialApp
(
home:
Material
(
child:
ExpansionTile
(
title:
Text
(
'Title'
),
controlAffinity:
ListTileControlAffinity
.
trailing
,
),
),
));
final
ListTile
listTile
=
tester
.
widget
(
find
.
byType
(
ListTile
));
expect
(
listTile
.
leading
,
isNull
);
expect
(
listTile
.
trailing
.
runtimeType
,
RotationTransition
);
});
testWidgets
(
'ExpansionTile leading controlAffinity test'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
const
MaterialApp
(
home:
Material
(
child:
ExpansionTile
(
title:
Text
(
'Title'
),
controlAffinity:
ListTileControlAffinity
.
leading
,
),
),
));
final
ListTile
listTile
=
tester
.
widget
(
find
.
byType
(
ListTile
));
expect
(
listTile
.
leading
.
runtimeType
,
RotationTransition
);
expect
(
listTile
.
trailing
,
isNull
);
});
testWidgets
(
'ExpansionTile override rotating icon test'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
const
MaterialApp
(
home:
Material
(
child:
ExpansionTile
(
title:
Text
(
'Title'
),
leading:
Icon
(
Icons
.
info
),
controlAffinity:
ListTileControlAffinity
.
leading
,
),
),
));
final
ListTile
listTile
=
tester
.
widget
(
find
.
byType
(
ListTile
));
expect
(
listTile
.
leading
.
runtimeType
,
Icon
);
expect
(
listTile
.
trailing
,
isNull
);
});
}
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