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
1157812b
Commit
1157812b
authored
May 09, 2017
by
Hans Muller
Committed by
GitHub
May 09, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added ExpansionTile and deprecated TwoLevelList et al (#9938)
parent
5b18fca0
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
263 additions
and
118 deletions
+263
-118
list_demo.dart
examples/flutter_gallery/lib/demo/material/list_demo.dart
+29
-15
two_level_list_demo.dart
...lutter_gallery/lib/demo/material/two_level_list_demo.dart
+8
-9
material.dart
packages/flutter/lib/material.dart
+1
-0
expansion_tile.dart
packages/flutter/lib/src/material/expansion_tile.dart
+181
-0
list_tile.dart
packages/flutter/lib/src/material/list_tile.dart
+0
-36
two_level_list.dart
packages/flutter/lib/src/material/two_level_list.dart
+32
-28
two_level_list_test.dart
packages/flutter/test/material/two_level_list_test.dart
+12
-30
No files found.
examples/flutter_gallery/lib/demo/material/list_demo.dart
View file @
1157812b
...
...
@@ -4,6 +4,20 @@
import
'package:flutter/material.dart'
;
enum
_MaterialListType
{
/// A list tile that contains a single line of text.
oneLine
,
/// A list tile that contains a [CircleAvatar] followed by a single line of text.
oneLineWithAvatar
,
/// A list tile that contains two lines of text.
twoLine
,
/// A list tile that contains three lines of text.
threeLine
,
}
class
ListDemo
extends
StatefulWidget
{
const
ListDemo
({
Key
key
})
:
super
(
key:
key
);
...
...
@@ -17,7 +31,7 @@ class _ListDemoState extends State<ListDemo> {
static
final
GlobalKey
<
ScaffoldState
>
scaffoldKey
=
new
GlobalKey
<
ScaffoldState
>();
PersistentBottomSheetController
<
Null
>
_bottomSheet
;
MaterialListType
_itemType
=
MaterialListType
.
threeLine
;
_MaterialListType
_itemType
=
_
MaterialListType
.
threeLine
;
bool
_dense
=
false
;
bool
_showAvatars
=
true
;
bool
_showIcons
=
false
;
...
...
@@ -27,7 +41,7 @@ class _ListDemoState extends State<ListDemo> {
'A'
,
'B'
,
'C'
,
'D'
,
'E'
,
'F'
,
'G'
,
'H'
,
'I'
,
'J'
,
'K'
,
'L'
,
'M'
,
'N'
,
];
void
changeItemType
(
MaterialListType
type
)
{
void
changeItemType
(
_
MaterialListType
type
)
{
setState
(()
{
_itemType
=
type
;
});
...
...
@@ -47,8 +61,8 @@ class _ListDemoState extends State<ListDemo> {
new
ListTile
(
dense:
true
,
title:
const
Text
(
'One-line'
),
trailing:
new
Radio
<
MaterialListType
>(
value:
_showAvatars
?
MaterialListType
.
oneLineWithAvatar
:
MaterialListType
.
oneLine
,
trailing:
new
Radio
<
_
MaterialListType
>(
value:
_showAvatars
?
_MaterialListType
.
oneLineWithAvatar
:
_
MaterialListType
.
oneLine
,
groupValue:
_itemType
,
onChanged:
changeItemType
,
)
...
...
@@ -56,8 +70,8 @@ class _ListDemoState extends State<ListDemo> {
new
ListTile
(
dense:
true
,
title:
const
Text
(
'Two-line'
),
trailing:
new
Radio
<
MaterialListType
>(
value:
MaterialListType
.
twoLine
,
trailing:
new
Radio
<
_
MaterialListType
>(
value:
_
MaterialListType
.
twoLine
,
groupValue:
_itemType
,
onChanged:
changeItemType
,
)
...
...
@@ -65,8 +79,8 @@ class _ListDemoState extends State<ListDemo> {
new
ListTile
(
dense:
true
,
title:
const
Text
(
'Three-line'
),
trailing:
new
Radio
<
MaterialListType
>(
value:
MaterialListType
.
threeLine
,
trailing:
new
Radio
<
_
MaterialListType
>(
value:
_
MaterialListType
.
threeLine
,
groupValue:
_itemType
,
onChanged:
changeItemType
,
),
...
...
@@ -143,15 +157,15 @@ class _ListDemoState extends State<ListDemo> {
Widget
buildListTile
(
BuildContext
context
,
String
item
)
{
Widget
secondary
;
if
(
_itemType
==
MaterialListType
.
twoLine
)
{
if
(
_itemType
==
_
MaterialListType
.
twoLine
)
{
secondary
=
const
Text
(
"Additional item information."
);
}
else
if
(
_itemType
==
MaterialListType
.
threeLine
)
{
}
else
if
(
_itemType
==
_
MaterialListType
.
threeLine
)
{
secondary
=
const
Text
(
"Even more additional list item information appears on line three."
,
);
}
return
new
ListTile
(
isThreeLine:
_itemType
==
MaterialListType
.
threeLine
,
isThreeLine:
_itemType
==
_
MaterialListType
.
threeLine
,
dense:
_dense
,
leading:
_showAvatars
?
new
CircleAvatar
(
child:
new
Text
(
item
))
:
null
,
title:
new
Text
(
'This item represents
$item
.'
),
...
...
@@ -165,14 +179,14 @@ class _ListDemoState extends State<ListDemo> {
final
String
layoutText
=
_dense
?
"
\
u2013 Dense"
:
""
;
String
itemTypeText
;
switch
(
_itemType
)
{
case
MaterialListType
.
oneLine
:
case
MaterialListType
.
oneLineWithAvatar
:
case
_
MaterialListType
.
oneLine
:
case
_
MaterialListType
.
oneLineWithAvatar
:
itemTypeText
=
'Single-line'
;
break
;
case
MaterialListType
.
twoLine
:
case
_
MaterialListType
.
twoLine
:
itemTypeText
=
'Two-line'
;
break
;
case
MaterialListType
.
threeLine
:
case
_
MaterialListType
.
threeLine
:
itemTypeText
=
'Three-line'
;
break
;
}
...
...
examples/flutter_gallery/lib/demo/material/two_level_list_demo.dart
View file @
1157812b
...
...
@@ -11,22 +11,21 @@ class TwoLevelListDemo extends StatelessWidget {
Widget
build
(
BuildContext
context
)
{
return
new
Scaffold
(
appBar:
new
AppBar
(
title:
const
Text
(
'Expand/collapse list control'
)),
body:
new
TwoLevelList
(
type:
MaterialListType
.
oneLine
,
body:
new
ListView
(
children:
<
Widget
>[
const
TwoLevelListItem
(
title:
const
Text
(
'Top'
)),
new
TwoLevelSublist
(
const
ListTile
(
title:
const
Text
(
'Top'
)),
new
ExpansionTile
(
title:
const
Text
(
'Sublist'
),
backgroundColor:
Theme
.
of
(
context
).
accentColor
.
withOpacity
(
0.025
),
children:
<
Widget
>[
const
TwoLevelListItem
(
title:
const
Text
(
'One'
)),
const
TwoLevelListItem
(
title:
const
Text
(
'Two'
)),
const
ListTile
(
title:
const
Text
(
'One'
)),
const
ListTile
(
title:
const
Text
(
'Two'
)),
// https://en.wikipedia.org/wiki/Free_Four
const
TwoLevelListItem
(
title:
const
Text
(
'Free'
)),
const
TwoLevelListItem
(
title:
const
Text
(
'Four'
))
const
ListTile
(
title:
const
Text
(
'Free'
)),
const
ListTile
(
title:
const
Text
(
'Four'
))
]
),
const
TwoLevelListItem
(
title:
const
Text
(
'Bottom'
))
const
ListTile
(
title:
const
Text
(
'Bottom'
))
]
)
);
...
...
packages/flutter/lib/material.dart
View file @
1157812b
...
...
@@ -40,6 +40,7 @@ export 'src/material/drawer_header.dart';
export
'src/material/dropdown.dart'
;
export
'src/material/expand_icon.dart'
;
export
'src/material/expansion_panel.dart'
;
export
'src/material/expansion_tile.dart'
;
export
'src/material/flat_button.dart'
;
export
'src/material/flexible_space_bar.dart'
;
export
'src/material/floating_action_button.dart'
;
...
...
packages/flutter/lib/src/material/expansion_tile.dart
0 → 100644
View file @
1157812b
// Copyright 2017 The Chromium 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
'colors.dart'
;
import
'icon.dart'
;
import
'icon_theme.dart'
;
import
'icon_theme_data.dart'
;
import
'icons.dart'
;
import
'list_tile.dart'
;
import
'theme.dart'
;
import
'theme_data.dart'
;
const
Duration
_kExpand
=
const
Duration
(
milliseconds:
200
);
/// A single-line [ListTile] with a trailing button that expands or collapses
/// the tile to reveal or hide the [children].
///
/// This widget is typically used with [ListView] to create an
/// "expand / collapse" list entry.
///
/// See also:
///
/// * [ListTile], useful for creating expansion tile [children] when the
/// expansion tile represents a sublist.
/// * The "Expand/collapse" section of
/// <https://material.io/guidelines/components/lists-controls.html>.
class
ExpansionTile
extends
StatefulWidget
{
/// Creates a single-line [ListTile] with a trailing button that expands or collapses
/// the tile to reveal or hide the [children].
const
ExpansionTile
({
Key
key
,
this
.
leading
,
@required
this
.
title
,
this
.
backgroundColor
,
this
.
onExpansionChanged
,
this
.
children
:
const
<
Widget
>[],
})
:
super
(
key:
key
);
/// A widget to display before the title.
///
/// Typically a [CircleAvatar] widget.
final
Widget
leading
;
/// The primary content of the list item.
///
/// Typically a [Text] widget.
final
Widget
title
;
/// Called when the tile expands or collapses.
///
/// When the tile starts expanding, this function is called with the value
/// `true`. When the tile starts collapsing, this function is called with
/// the value false.
final
ValueChanged
<
bool
>
onExpansionChanged
;
/// The widgets that are displayed when the tile expands.
///
/// Typically [ListTile] widgets.
final
List
<
Widget
>
children
;
/// The color to display behind the sublist when expanded.
final
Color
backgroundColor
;
@override
_ExpansionTileState
createState
()
=>
new
_ExpansionTileState
();
}
class
_ExpansionTileState
extends
State
<
ExpansionTile
>
with
SingleTickerProviderStateMixin
{
AnimationController
_controller
;
CurvedAnimation
_easeOutAnimation
;
CurvedAnimation
_easeInAnimation
;
ColorTween
_borderColor
;
ColorTween
_headerColor
;
ColorTween
_iconColor
;
ColorTween
_backgroundColor
;
Animation
<
double
>
_iconTurns
;
bool
_isExpanded
=
false
;
@override
void
initState
()
{
super
.
initState
();
_controller
=
new
AnimationController
(
duration:
_kExpand
,
vsync:
this
);
_easeOutAnimation
=
new
CurvedAnimation
(
parent:
_controller
,
curve:
Curves
.
easeOut
);
_easeInAnimation
=
new
CurvedAnimation
(
parent:
_controller
,
curve:
Curves
.
easeIn
);
_borderColor
=
new
ColorTween
(
begin:
Colors
.
transparent
);
_headerColor
=
new
ColorTween
();
_iconColor
=
new
ColorTween
();
_iconTurns
=
new
Tween
<
double
>(
begin:
0.0
,
end:
0.5
).
animate
(
_easeInAnimation
);
_backgroundColor
=
new
ColorTween
();
_isExpanded
=
PageStorage
.
of
(
context
)?.
readState
(
context
)
??
false
;
if
(
_isExpanded
)
_controller
.
value
=
1.0
;
}
@override
void
dispose
()
{
_controller
.
dispose
();
super
.
dispose
();
}
void
_handleTap
()
{
setState
(()
{
_isExpanded
=
!
_isExpanded
;
if
(
_isExpanded
)
_controller
.
forward
();
else
_controller
.
reverse
();
PageStorage
.
of
(
context
)?.
writeState
(
context
,
_isExpanded
);
});
if
(
widget
.
onExpansionChanged
!=
null
)
widget
.
onExpansionChanged
(
_isExpanded
);
}
Widget
_buildChildren
(
BuildContext
context
,
Widget
child
)
{
final
Color
borderSideColor
=
_borderColor
.
evaluate
(
_easeOutAnimation
);
final
Color
titleColor
=
_headerColor
.
evaluate
(
_easeInAnimation
);
return
new
Container
(
decoration:
new
BoxDecoration
(
color:
_backgroundColor
.
evaluate
(
_easeOutAnimation
),
border:
new
Border
(
top:
new
BorderSide
(
color:
borderSideColor
),
bottom:
new
BorderSide
(
color:
borderSideColor
),
)
),
child:
new
Column
(
mainAxisSize:
MainAxisSize
.
min
,
children:
<
Widget
>[
IconTheme
.
merge
(
data:
new
IconThemeData
(
color:
_iconColor
.
evaluate
(
_easeInAnimation
)),
child:
new
ListTile
(
onTap:
_handleTap
,
leading:
widget
.
leading
,
title:
new
DefaultTextStyle
(
style:
Theme
.
of
(
context
).
textTheme
.
subhead
.
copyWith
(
color:
titleColor
),
child:
widget
.
title
,
),
trailing:
new
RotationTransition
(
turns:
_iconTurns
,
child:
const
Icon
(
Icons
.
expand_more
),
),
),
),
new
ClipRect
(
child:
new
Align
(
heightFactor:
_easeInAnimation
.
value
,
child:
child
,
),
),
],
),
);
}
@override
Widget
build
(
BuildContext
context
)
{
final
ThemeData
theme
=
Theme
.
of
(
context
);
_borderColor
.
end
=
theme
.
dividerColor
;
_headerColor
..
begin
=
theme
.
textTheme
.
subhead
.
color
..
end
=
theme
.
accentColor
;
_iconColor
..
begin
=
theme
.
unselectedWidgetColor
..
end
=
theme
.
accentColor
;
_backgroundColor
..
begin
=
Colors
.
transparent
..
end
=
widget
.
backgroundColor
??
Colors
.
transparent
;
return
new
AnimatedBuilder
(
animation:
_controller
.
view
,
builder:
_buildChildren
,
child:
new
Column
(
children:
widget
.
children
),
);
}
}
packages/flutter/lib/src/material/list_tile.dart
View file @
1157812b
...
...
@@ -13,27 +13,6 @@ import 'icon_theme_data.dart';
import
'ink_well.dart'
;
import
'theme.dart'
;
/// The kind of list tiles contained in a material design list.
///
/// See also:
///
/// * [ListTile]
/// * [kListTileExtent]
/// * <https://material.google.com/components/lists.html#lists-specs>
enum
MaterialListType
{
/// A list tile that contains a single line of text.
oneLine
,
/// A list tile that contains a [CircleAvatar] followed by a single line of text.
oneLineWithAvatar
,
/// A list tile that contains two lines of text.
twoLine
,
/// A list tile that contains three lines of text.
threeLine
,
}
/// Defines the title font used for [ListTile] descendants of a [ListTileTheme].
///
/// List tiles that appear in a [Drawer] use the theme's [TextTheme.body2]
...
...
@@ -47,21 +26,6 @@ enum ListTileStyle {
drawer
,
}
/// The vertical extent of the different types of material list tiles.
///
/// See also:
///
/// * [MaterialListType]
/// * [ListTile]
/// * [kListTileExtent]
/// * <https://material.google.com/components/lists.html#lists-specs>
Map
<
MaterialListType
,
double
>
kListTileExtent
=
const
<
MaterialListType
,
double
>{
MaterialListType
.
oneLine
:
48.0
,
MaterialListType
.
oneLineWithAvatar
:
56.0
,
MaterialListType
.
twoLine
:
72.0
,
MaterialListType
.
threeLine
:
88.0
,
};
/// An inherited widget that defines color and style parameters for [ListTile]s
/// in this widget's subtree.
///
...
...
packages/flutter/lib/src/material/two_level_list.dart
View file @
1157812b
...
...
@@ -14,19 +14,35 @@ import 'list_tile.dart';
import
'theme.dart'
;
import
'theme_data.dart'
;
/// This enum is deprecated. Please use [ListTileTheme] instead.
enum
MaterialListType
{
/// A list tile that contains a single line of text.
oneLine
,
/// A list tile that contains a [CircleAvatar] followed by a single line of text.
oneLineWithAvatar
,
/// A list tile that contains two lines of text.
twoLine
,
/// A list tile that contains three lines of text.
threeLine
,
}
/// This constant is deprecated. The [ListTile] class sizes itself based on
/// its content and [ListTileTheme].
@deprecated
Map
<
MaterialListType
,
double
>
kListTileExtent
=
const
<
MaterialListType
,
double
>{
MaterialListType
.
oneLine
:
48.0
,
MaterialListType
.
oneLineWithAvatar
:
56.0
,
MaterialListType
.
twoLine
:
72.0
,
MaterialListType
.
threeLine
:
88.0
,
};
const
Duration
_kExpand
=
const
Duration
(
milliseconds:
200
);
/// An item in a [TwoLevelList] or a [TwoLevelSublist].
///
/// A two-level list item is similar to a [ListTile], but a two-level list item
/// automatically sizes itself to fit properly within its ancestor
/// [TwoLevelList].
///
/// See also:
///
/// * [TwoLevelList]
/// * [TwoLevelSublist]
/// * [ListTile]
/// This class is deprecated. Please use [ListTile] instead.
@deprecated
class
TwoLevelListItem
extends
StatelessWidget
{
/// Creates an item in a two-level list.
const
TwoLevelListItem
({
...
...
@@ -91,16 +107,8 @@ class TwoLevelListItem extends StatelessWidget {
}
}
/// An item in a [TwoLevelList] that can expand and collapse.
///
/// A two-level sublist is similar to a [ListTile], but the trailing widget is
/// a button that expands or collapses a sublist of items.
///
/// See also:
///
/// * [TwoLevelList]
/// * [TwoLevelListItem]
/// * [ListTile]
/// This class is deprecated. Please use [ExpansionTile] instead.
@deprecated
class
TwoLevelSublist
extends
StatefulWidget
{
/// Creates an item in a two-level list that can expland and collapse.
const
TwoLevelSublist
({
...
...
@@ -141,6 +149,7 @@ class TwoLevelSublist extends StatefulWidget {
_TwoLevelSublistState
createState
()
=>
new
_TwoLevelSublistState
();
}
@deprecated
class
_TwoLevelSublistState
extends
State
<
TwoLevelSublist
>
with
SingleTickerProviderStateMixin
{
AnimationController
_controller
;
CurvedAnimation
_easeOutAnimation
;
...
...
@@ -247,13 +256,8 @@ class _TwoLevelSublistState extends State<TwoLevelSublist> with SingleTickerProv
}
}
/// A scrollable list of items that can expand and collapse.
///
/// See also:
///
/// * [TwoLevelSublist]
/// * [TwoLevelListItem]
/// * [ListView], for lists that only have one level.
/// This class is deprecated. Please use [ListView] and [ListTileTheme] instead.
@deprecated
class
TwoLevelList
extends
StatelessWidget
{
/// Creates a scrollable list of items that can expand and collapse.
///
...
...
packages/flutter/test/material/two_level_list_test.dart
View file @
1157812b
...
...
@@ -7,24 +7,6 @@ import 'package:flutter/widgets.dart';
import
'package:flutter/material.dart'
;
void
main
(
)
{
testWidgets
(
'TwoLevelList default control'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
const
Center
(
child:
const
TwoLevelList
()));
await
tester
.
pumpWidget
(
new
Material
(
child:
new
Center
(
child:
new
TwoLevelList
(
children:
<
Widget
>[
const
TwoLevelSublist
(
title:
const
Text
(
'Title'
),
)
]
)
)
)
);
});
testWidgets
(
'TwoLevelList basics'
,
(
WidgetTester
tester
)
async
{
final
Key
topKey
=
new
UniqueKey
();
final
Key
sublistKey
=
new
UniqueKey
();
...
...
@@ -34,18 +16,18 @@ void main() {
'/'
:
(
_
)
{
return
new
Material
(
child:
new
SingleChildScrollView
(
child:
new
TwoLevelList
(
child:
new
Column
(
children:
<
Widget
>[
new
TwoLevelListItem
(
title:
const
Text
(
'Top'
),
key:
topKey
),
new
TwoLevelSublist
(
new
ListTile
(
title:
const
Text
(
'Top'
),
key:
topKey
),
new
ExpansionTile
(
key:
sublistKey
,
title:
const
Text
(
'Sublist'
),
children:
<
Widget
>[
const
TwoLevelListItem
(
title:
const
Text
(
'0'
)),
const
TwoLevelListItem
(
title:
const
Text
(
'1'
))
const
ListTile
(
title:
const
Text
(
'0'
)),
const
ListTile
(
title:
const
Text
(
'1'
))
]
),
new
TwoLevelListItem
(
title:
const
Text
(
'Bottom'
),
key:
bottomKey
)
new
ListTile
(
title:
const
Text
(
'Bottom'
),
key:
bottomKey
)
]
)
)
...
...
@@ -85,23 +67,23 @@ void main() {
expect
(
getY
(
bottomKey
)
-
getY
(
sublistKey
),
greaterThan
(
getHeight
(
bottomKey
)));
});
testWidgets
(
'on
Ope
nChanged callback'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'on
Expansio
nChanged callback'
,
(
WidgetTester
tester
)
async
{
bool
didChangeOpen
;
final
Map
<
String
,
WidgetBuilder
>
routes
=
<
String
,
WidgetBuilder
>{
'/'
:
(
_
)
{
return
new
Material
(
child:
new
SingleChildScrollView
(
child:
new
TwoLevelList
(
child:
new
Column
(
children:
<
Widget
>[
new
TwoLevelSublist
(
new
ExpansionTile
(
title:
const
Text
(
'Sublist'
),
on
Ope
nChanged:
(
bool
opened
)
{
on
Expansio
nChanged:
(
bool
opened
)
{
didChangeOpen
=
opened
;
},
children:
<
Widget
>[
const
TwoLevelListItem
(
title:
const
Text
(
'0'
)),
const
TwoLevelListItem
(
title:
const
Text
(
'1'
))
const
ListTile
(
title:
const
Text
(
'0'
)),
const
ListTile
(
title:
const
Text
(
'1'
))
]
),
]
...
...
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