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
09e8c2ff
Commit
09e8c2ff
authored
May 12, 2017
by
Hans Muller
Committed by
GitHub
May 12, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update ExpansionTile, added a sample app (#10019)
parent
ff0aa513
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
189 additions
and
3 deletions
+189
-3
expansion_tile_sample.dart
examples/catalog/lib/expansion_tile_sample.dart
+87
-0
expansion_tile_sample_test.dart
examples/catalog/test/expansion_tile_sample_test.dart
+91
-0
expansion_tile.dart
packages/flutter/lib/src/material/expansion_tile.dart
+11
-3
No files found.
examples/catalog/lib/expansion_tile_sample.dart
0 → 100644
View file @
09e8c2ff
// 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/material.dart'
;
class
Entry
{
Entry
(
this
.
title
,
[
this
.
children
=
const
<
Entry
>[]]);
final
String
title
;
final
List
<
Entry
>
children
;
}
final
List
<
Entry
>
data
=
<
Entry
>[
new
Entry
(
'Chapter A'
,
<
Entry
>[
new
Entry
(
'Section A0'
,
<
Entry
>[
new
Entry
(
'Item A0.1'
),
new
Entry
(
'Item A0.2'
),
new
Entry
(
'Item A0.3'
),
],
),
new
Entry
(
'Section A1'
),
new
Entry
(
'Section A2'
),
],
),
new
Entry
(
'Chapter B'
,
<
Entry
>[
new
Entry
(
'Section B0'
),
new
Entry
(
'Section B1'
),
],
),
new
Entry
(
'Chapter C'
,
<
Entry
>[
new
Entry
(
'Section C0'
),
new
Entry
(
'Section C1'
),
new
Entry
(
'Section C2'
,
<
Entry
>[
new
Entry
(
'Item C2.0'
),
new
Entry
(
'Item C2.1'
),
new
Entry
(
'Item C2.2'
),
new
Entry
(
'Item C2.3'
),
],
),
],
),
];
class
EntryItem
extends
StatelessWidget
{
EntryItem
(
this
.
entry
);
final
Entry
entry
;
Widget
_buildTiles
(
Entry
root
)
{
if
(
root
.
children
.
isEmpty
)
return
new
ListTile
(
title:
new
Text
(
root
.
title
));
return
new
ExpansionTile
(
key:
new
ValueKey
<
Entry
>(
root
),
title:
new
Text
(
root
.
title
),
children:
root
.
children
.
map
(
_buildTiles
).
toList
(),
);
}
@override
Widget
build
(
BuildContext
context
)
{
return
_buildTiles
(
entry
);
}
}
class
ExpansionTileSample
extends
StatelessWidget
{
@override
Widget
build
(
BuildContext
context
)
{
return
new
Scaffold
(
appBar:
new
AppBar
(
title:
const
Text
(
'ExpansionTile'
),
),
body:
new
ListView
.
builder
(
itemBuilder:
(
BuildContext
context
,
int
index
)
=>
new
EntryItem
(
data
[
index
]),
itemCount:
data
.
length
,
),
);
}
}
void
main
(
)
{
runApp
(
new
MaterialApp
(
home:
new
ExpansionTileSample
()));
}
examples/catalog/test/expansion_tile_sample_test.dart
0 → 100644
View file @
09e8c2ff
// 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/material.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'../lib/expansion_tile_sample.dart'
as
expansion_tile_sample
;
import
'../lib/expansion_tile_sample.dart'
show
Entry
;
void
main
(
)
{
testWidgets
(
"expansion_tile sample smoke test"
,
(
WidgetTester
tester
)
async
{
expansion_tile_sample
.
main
();
await
tester
.
pump
();
// Initially only the top level EntryItems (the "chapters") are present.
for
(
Entry
chapter
in
expansion_tile_sample
.
data
)
{
expect
(
find
.
text
(
chapter
.
title
),
findsOneWidget
);
for
(
Entry
section
in
chapter
.
children
)
{
expect
(
find
.
text
(
section
.
title
),
findsNothing
);
for
(
Entry
item
in
section
.
children
)
expect
(
find
.
text
(
item
.
title
),
findsNothing
);
}
}
Future
<
Null
>
scrollUpOneEntry
()
async
{
await
tester
.
dragFrom
(
const
Offset
(
200.0
,
200.0
),
const
Offset
(
0.0
,
-
88.00
));
await
tester
.
pumpAndSettle
();
}
Future
<
Null
>
tapEntry
(
String
title
)
async
{
await
tester
.
tap
(
find
.
text
(
title
));
await
tester
.
pumpAndSettle
();
}
// Expand the chapters. Now the chapter and sections, but not the
// items, should be present.
for
(
Entry
chapter
in
expansion_tile_sample
.
data
.
reversed
)
await
tapEntry
(
chapter
.
title
);
for
(
Entry
chapter
in
expansion_tile_sample
.
data
)
{
expect
(
find
.
text
(
chapter
.
title
),
findsOneWidget
);
for
(
Entry
section
in
chapter
.
children
)
{
expect
(
find
.
text
(
section
.
title
),
findsOneWidget
);
await
scrollUpOneEntry
();
for
(
Entry
item
in
section
.
children
)
expect
(
find
.
text
(
item
.
title
),
findsNothing
);
}
await
scrollUpOneEntry
();
}
// - scroll to the top -
await
tester
.
flingFrom
(
const
Offset
(
200.0
,
200.0
),
const
Offset
(
0.0
,
100.0
),
5000.0
);
await
tester
.
pumpAndSettle
();
// Expand the sections. Now Widgets for all three levels should be present.
for
(
Entry
chapter
in
expansion_tile_sample
.
data
)
{
for
(
Entry
section
in
chapter
.
children
)
{
await
tapEntry
(
section
.
title
);
await
scrollUpOneEntry
();
}
await
scrollUpOneEntry
();
}
// We're scrolled to the bottom so the very last item is visible.
// Working in reverse order, so we don't need to do anymore scrolling,
// check that everything is visible and close the sections and
// chapters as we go up.
for
(
Entry
chapter
in
expansion_tile_sample
.
data
.
reversed
)
{
expect
(
find
.
text
(
chapter
.
title
),
findsOneWidget
);
for
(
Entry
section
in
chapter
.
children
.
reversed
)
{
expect
(
find
.
text
(
section
.
title
),
findsOneWidget
);
for
(
Entry
item
in
section
.
children
.
reversed
)
expect
(
find
.
text
(
item
.
title
),
findsOneWidget
);
await
tapEntry
(
section
.
title
);
// close the section
}
await
tapEntry
(
chapter
.
title
);
// close the chapter
}
// Finally only the top level EntryItems (the "chapters") are present.
for
(
Entry
chapter
in
expansion_tile_sample
.
data
)
{
expect
(
find
.
text
(
chapter
.
title
),
findsOneWidget
);
for
(
Entry
section
in
chapter
.
children
)
{
expect
(
find
.
text
(
section
.
title
),
findsNothing
);
for
(
Entry
item
in
section
.
children
)
expect
(
find
.
text
(
item
.
title
),
findsNothing
);
}
}
});
}
packages/flutter/lib/src/material/expansion_tile.dart
View file @
09e8c2ff
...
...
@@ -20,7 +20,9 @@ const Duration _kExpand = const Duration(milliseconds: 200);
/// the tile to reveal or hide the [children].
///
/// This widget is typically used with [ListView] to create an
/// "expand / collapse" list entry.
/// "expand / collapse" list entry. When used with scrolling widgets like
/// [ListView], a unique [key] must be specified to enable the [ExpansionTile] to
/// save and restore its expanded state when it is scrolled in and out of view.
///
/// See also:
///
...
...
@@ -110,7 +112,11 @@ class _ExpansionTileState extends State<ExpansionTile> with SingleTickerProvider
if
(
_isExpanded
)
_controller
.
forward
();
else
_controller
.
reverse
();
_controller
.
reverse
().
then
((
Null
value
)
{
setState
(()
{
// Rebuild without widget.children.
});
});
PageStorage
.
of
(
context
)?.
writeState
(
context
,
_isExpanded
);
});
if
(
widget
.
onExpansionChanged
!=
null
)
...
...
@@ -172,10 +178,12 @@ class _ExpansionTileState extends State<ExpansionTile> with SingleTickerProvider
..
begin
=
Colors
.
transparent
..
end
=
widget
.
backgroundColor
??
Colors
.
transparent
;
final
bool
closed
=
!
_isExpanded
&&
_controller
.
isDismissed
;
return
new
AnimatedBuilder
(
animation:
_controller
.
view
,
builder:
_buildChildren
,
child:
new
Column
(
children:
widget
.
children
),
child:
closed
?
null
:
new
Column
(
children:
widget
.
children
),
);
}
}
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