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
fd71de13
Unverified
Commit
fd71de13
authored
Feb 25, 2022
by
Taha Tesser
Committed by
GitHub
Feb 25, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[ReorderableListView] Add `footer` (#92086)
parent
839bd631
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
99 additions
and
19 deletions
+99
-19
reorderable_list.dart
packages/flutter/lib/src/material/reorderable_list.dart
+27
-13
reorderable_list_test.dart
packages/flutter/test/material/reorderable_list_test.dart
+72
-6
No files found.
packages/flutter/lib/src/material/reorderable_list.dart
View file @
fd71de13
...
...
@@ -72,6 +72,7 @@ class ReorderableListView extends StatefulWidget {
this
.
buildDefaultDragHandles
=
true
,
this
.
padding
,
this
.
header
,
this
.
footer
,
this
.
scrollDirection
=
Axis
.
vertical
,
this
.
reverse
=
false
,
this
.
scrollController
,
...
...
@@ -141,6 +142,7 @@ class ReorderableListView extends StatefulWidget {
this
.
buildDefaultDragHandles
=
true
,
this
.
padding
,
this
.
header
,
this
.
footer
,
this
.
scrollDirection
=
Axis
.
vertical
,
this
.
reverse
=
false
,
this
.
scrollController
,
...
...
@@ -214,6 +216,11 @@ class ReorderableListView extends StatefulWidget {
/// If null, no header will appear before the list.
final
Widget
?
header
;
/// A non-reorderable footer item to show after the items of the list.
///
/// If null, no footer will appear after the list.
final
Widget
?
footer
;
/// {@macro flutter.widgets.scroll_view.scrollDirection}
final
Axis
scrollDirection
;
...
...
@@ -426,39 +433,41 @@ class _ReorderableListViewState extends State<ReorderableListView> {
assert
(
debugCheckHasMaterialLocalizations
(
context
));
assert
(
debugCheckHasOverlay
(
context
));
// If there is a header we can't just apply the padding to the list,
// so we break it up into padding for the header and padding for the list.
// If there is a header
or footer
we can't just apply the padding to the list,
// so we break it up into padding for the header
, footer
and padding for the list.
final
EdgeInsets
padding
=
widget
.
padding
??
EdgeInsets
.
zero
;
late
final
EdgeInsets
headerPadding
;
late
final
EdgeInsets
footerPadding
;
late
final
EdgeInsets
listPadding
;
if
(
widget
.
header
==
null
)
{
if
(
widget
.
header
==
null
&&
widget
.
footer
==
null
)
{
headerPadding
=
EdgeInsets
.
zero
;
footerPadding
=
EdgeInsets
.
zero
;
listPadding
=
padding
;
}
else
{
}
else
if
(
widget
.
header
!=
null
||
widget
.
footer
!=
null
)
{
switch
(
widget
.
scrollDirection
)
{
case
Axis
.
horizontal
:
if
(
widget
.
reverse
)
{
// Header on the right
headerPadding
=
EdgeInsets
.
fromLTRB
(
0
,
padding
.
top
,
padding
.
right
,
padding
.
bottom
);
listPadding
=
EdgeInsets
.
fromLTRB
(
padding
.
left
,
padding
.
top
,
0
,
padding
.
bottom
);
listPadding
=
EdgeInsets
.
fromLTRB
(
widget
.
footer
!=
null
?
0
:
padding
.
left
,
padding
.
top
,
widget
.
header
!=
null
?
0
:
padding
.
right
,
padding
.
bottom
);
footerPadding
=
EdgeInsets
.
fromLTRB
(
padding
.
left
,
padding
.
top
,
0
,
padding
.
bottom
);
}
else
{
// Header on the left
headerPadding
=
EdgeInsets
.
fromLTRB
(
padding
.
left
,
padding
.
top
,
0
,
padding
.
bottom
);
listPadding
=
EdgeInsets
.
fromLTRB
(
0
,
padding
.
top
,
padding
.
right
,
padding
.
bottom
);
listPadding
=
EdgeInsets
.
fromLTRB
(
widget
.
header
!=
null
?
0
:
padding
.
left
,
padding
.
top
,
widget
.
footer
!=
null
?
0
:
padding
.
right
,
padding
.
bottom
);
footerPadding
=
EdgeInsets
.
fromLTRB
(
0
,
padding
.
top
,
padding
.
right
,
padding
.
bottom
);
}
break
;
case
Axis
.
vertical
:
if
(
widget
.
reverse
)
{
// Header on the bottom
headerPadding
=
EdgeInsets
.
fromLTRB
(
padding
.
left
,
0
,
padding
.
right
,
padding
.
bottom
);
listPadding
=
EdgeInsets
.
fromLTRB
(
padding
.
left
,
padding
.
top
,
padding
.
right
,
0
);
listPadding
=
EdgeInsets
.
fromLTRB
(
padding
.
left
,
widget
.
footer
!=
null
?
0
:
padding
.
top
,
padding
.
right
,
widget
.
header
!=
null
?
0
:
padding
.
bottom
);
footerPadding
=
EdgeInsets
.
fromLTRB
(
padding
.
left
,
padding
.
top
,
padding
.
right
,
0
);
}
else
{
// Header on the top
headerPadding
=
EdgeInsets
.
fromLTRB
(
padding
.
left
,
padding
.
top
,
padding
.
right
,
0
);
listPadding
=
EdgeInsets
.
fromLTRB
(
padding
.
left
,
0
,
padding
.
right
,
padding
.
bottom
);
listPadding
=
EdgeInsets
.
fromLTRB
(
padding
.
left
,
widget
.
header
!=
null
?
0
:
padding
.
top
,
padding
.
right
,
widget
.
footer
!=
null
?
0
:
padding
.
bottom
);
footerPadding
=
EdgeInsets
.
fromLTRB
(
padding
.
left
,
0
,
padding
.
right
,
padding
.
bottom
);
}
break
;
break
;
}
}
...
...
@@ -494,6 +503,11 @@ class _ReorderableListViewState extends State<ReorderableListView> {
proxyDecorator:
widget
.
proxyDecorator
??
_proxyDecorator
,
),
),
if
(
widget
.
footer
!=
null
)
SliverPadding
(
padding:
footerPadding
,
sliver:
SliverToBoxAdapter
(
child:
widget
.
footer
),
),
],
);
}
...
...
packages/flutter/test/material/reorderable_list_test.dart
View file @
fd71de13
...
...
@@ -36,6 +36,7 @@ void main() {
Widget
build
({
Widget
?
header
,
Widget
?
footer
,
Axis
scrollDirection
=
Axis
.
vertical
,
bool
reverse
=
false
,
EdgeInsets
padding
=
EdgeInsets
.
zero
,
...
...
@@ -51,6 +52,7 @@ void main() {
width:
itemHeight
*
10
,
child:
ReorderableListView
(
header:
header
,
footer:
footer
,
scrollDirection:
scrollDirection
,
onReorder:
onReorder
,
reverse:
reverse
,
...
...
@@ -157,6 +159,20 @@ void main() {
expect
(
listItems
,
orderedEquals
(<
String
>[
'Item 2'
,
'Item 3'
,
'Item 4'
,
'Item 1'
]));
});
testWidgets
(
'properly reorders with a footer'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
build
(
footer:
const
Text
(
'Footer Text'
)));
expect
(
find
.
text
(
'Footer Text'
),
findsOneWidget
);
expect
(
listItems
,
orderedEquals
(
originalListItems
));
await
longPressDrag
(
tester
,
tester
.
getCenter
(
find
.
text
(
'Item 1'
)),
tester
.
getCenter
(
find
.
text
(
'Item 4'
))
+
const
Offset
(
0.0
,
itemHeight
*
2
),
);
await
tester
.
pumpAndSettle
();
expect
(
find
.
text
(
'Footer Text'
),
findsOneWidget
);
expect
(
listItems
,
orderedEquals
(<
String
>[
'Item 2'
,
'Item 3'
,
'Item 4'
,
'Item 1'
]));
});
testWidgets
(
'properly determines the vertical drop area extents'
,
(
WidgetTester
tester
)
async
{
final
Widget
reorderableListView
=
ReorderableListView
(
onReorder:
(
int
oldIndex
,
int
newIndex
)
{
},
...
...
@@ -764,6 +780,29 @@ void main() {
expect
(
listItems
,
orderedEquals
(<
String
>[
'Item 2'
,
'Item 4'
,
'Item 3'
,
'Item 1'
]));
});
testWidgets
(
'properly reorders with a footer'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
build
(
footer:
const
Text
(
'Footer Text'
),
scrollDirection:
Axis
.
horizontal
));
expect
(
find
.
text
(
'Footer Text'
),
findsOneWidget
);
expect
(
listItems
,
orderedEquals
(
originalListItems
));
await
longPressDrag
(
tester
,
tester
.
getCenter
(
find
.
text
(
'Item 1'
)),
tester
.
getCenter
(
find
.
text
(
'Item 4'
))
+
const
Offset
(
itemHeight
*
2
,
0.0
),
);
await
tester
.
pumpAndSettle
();
expect
(
find
.
text
(
'Footer Text'
),
findsOneWidget
);
expect
(
listItems
,
orderedEquals
(<
String
>[
'Item 2'
,
'Item 3'
,
'Item 4'
,
'Item 1'
]));
await
tester
.
pumpWidget
(
build
(
footer:
const
Text
(
'Footer Text'
),
scrollDirection:
Axis
.
horizontal
));
await
longPressDrag
(
tester
,
tester
.
getCenter
(
find
.
text
(
'Item 4'
)),
tester
.
getCenter
(
find
.
text
(
'Item 3'
)),
);
await
tester
.
pumpAndSettle
();
expect
(
find
.
text
(
'Footer Text'
),
findsOneWidget
);
expect
(
listItems
,
orderedEquals
(<
String
>[
'Item 2'
,
'Item 4'
,
'Item 3'
,
'Item 1'
]));
});
testWidgets
(
'properly determines the horizontal drop area extents'
,
(
WidgetTester
tester
)
async
{
final
Widget
reorderableListView
=
ReorderableListView
(
scrollDirection:
Axis
.
horizontal
,
...
...
@@ -1242,7 +1281,7 @@ void main() {
});
group
(
'Padding'
,
()
{
testWidgets
(
'Padding with no header'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'Padding with no header
& footer
'
,
(
WidgetTester
tester
)
async
{
const
EdgeInsets
padding
=
EdgeInsets
.
fromLTRB
(
10
,
20
,
30
,
40
);
// Vertical
...
...
@@ -1256,35 +1295,62 @@ void main() {
expect
(
tester
.
getRect
(
find
.
byKey
(
const
Key
(
'Item 4'
))),
const
Rect
.
fromLTRB
(
154
,
20
,
202
,
560
));
});
testWidgets
(
'Padding with header'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'Padding with header
or footer
'
,
(
WidgetTester
tester
)
async
{
const
EdgeInsets
padding
=
EdgeInsets
.
fromLTRB
(
10
,
20
,
30
,
40
);
const
Key
headerKey
=
Key
(
'Header'
);
const
Key
footerKey
=
Key
(
'Footer'
);
const
Widget
verticalHeader
=
SizedBox
(
key:
headerKey
,
height:
10
);
const
Widget
horizontalHeader
=
SizedBox
(
key:
headerKey
,
width:
10
);
const
Widget
verticalFooter
=
SizedBox
(
key:
footerKey
,
height:
10
);
const
Widget
horizontalFooter
=
SizedBox
(
key:
footerKey
,
width:
10
);
// Vertical
// Vertical
Header
await
tester
.
pumpWidget
(
build
(
padding:
padding
,
header:
verticalHeader
));
expect
(
tester
.
getRect
(
find
.
byKey
(
headerKey
)),
const
Rect
.
fromLTRB
(
10
,
20
,
770
,
30
));
expect
(
tester
.
getRect
(
find
.
byKey
(
const
Key
(
'Item 1'
))),
const
Rect
.
fromLTRB
(
10
,
30
,
770
,
78
));
expect
(
tester
.
getRect
(
find
.
byKey
(
const
Key
(
'Item 4'
))),
const
Rect
.
fromLTRB
(
10
,
174
,
770
,
222
));
// Vertical, reversed
// Vertical Footer
await
tester
.
pumpWidget
(
build
(
padding:
padding
,
footer:
verticalFooter
));
expect
(
tester
.
getRect
(
find
.
byKey
(
footerKey
)),
const
Rect
.
fromLTRB
(
10
,
212
,
770
,
222
));
expect
(
tester
.
getRect
(
find
.
byKey
(
const
Key
(
'Item 1'
))),
const
Rect
.
fromLTRB
(
10
,
20
,
770
,
68
));
expect
(
tester
.
getRect
(
find
.
byKey
(
const
Key
(
'Item 4'
))),
const
Rect
.
fromLTRB
(
10
,
164
,
770
,
212
));
// Vertical Header, reversed
await
tester
.
pumpWidget
(
build
(
padding:
padding
,
header:
verticalHeader
,
reverse:
true
));
expect
(
tester
.
getRect
(
find
.
byKey
(
headerKey
)),
const
Rect
.
fromLTRB
(
10
,
550
,
770
,
560
));
expect
(
tester
.
getRect
(
find
.
byKey
(
const
Key
(
'Item 1'
))),
const
Rect
.
fromLTRB
(
10
,
502
,
770
,
550
));
expect
(
tester
.
getRect
(
find
.
byKey
(
const
Key
(
'Item 4'
))),
const
Rect
.
fromLTRB
(
10
,
358
,
770
,
406
));
// Horizontal
// Vertical Footer, reversed
await
tester
.
pumpWidget
(
build
(
padding:
padding
,
footer:
verticalFooter
,
reverse:
true
));
expect
(
tester
.
getRect
(
find
.
byKey
(
footerKey
)),
const
Rect
.
fromLTRB
(
10
,
358
,
770
,
368
));
expect
(
tester
.
getRect
(
find
.
byKey
(
const
Key
(
'Item 1'
))),
const
Rect
.
fromLTRB
(
10
,
512
,
770
,
560
));
expect
(
tester
.
getRect
(
find
.
byKey
(
const
Key
(
'Item 4'
))),
const
Rect
.
fromLTRB
(
10
,
368
,
770
,
416
));
// Horizontal Header
await
tester
.
pumpWidget
(
build
(
padding:
padding
,
header:
horizontalHeader
,
scrollDirection:
Axis
.
horizontal
));
expect
(
tester
.
getRect
(
find
.
byKey
(
headerKey
)),
const
Rect
.
fromLTRB
(
10
,
20
,
20
,
560
));
expect
(
tester
.
getRect
(
find
.
byKey
(
const
Key
(
'Item 1'
))),
const
Rect
.
fromLTRB
(
20
,
20
,
68
,
560
));
expect
(
tester
.
getRect
(
find
.
byKey
(
const
Key
(
'Item 4'
))),
const
Rect
.
fromLTRB
(
164
,
20
,
212
,
560
));
// Horizontal, reversed
// // Horizontal Footer
await
tester
.
pumpWidget
(
build
(
padding:
padding
,
footer:
horizontalFooter
,
scrollDirection:
Axis
.
horizontal
));
expect
(
tester
.
getRect
(
find
.
byKey
(
footerKey
)),
const
Rect
.
fromLTRB
(
202
,
20
,
212
,
560
));
expect
(
tester
.
getRect
(
find
.
byKey
(
const
Key
(
'Item 1'
))),
const
Rect
.
fromLTRB
(
10
,
20
,
58
,
560
));
expect
(
tester
.
getRect
(
find
.
byKey
(
const
Key
(
'Item 4'
))),
const
Rect
.
fromLTRB
(
154
,
20
,
202
,
560
));
// Horizontal Header, reversed
await
tester
.
pumpWidget
(
build
(
padding:
padding
,
header:
horizontalHeader
,
scrollDirection:
Axis
.
horizontal
,
reverse:
true
));
expect
(
tester
.
getRect
(
find
.
byKey
(
headerKey
)),
const
Rect
.
fromLTRB
(
760
,
20
,
770
,
560
));
expect
(
tester
.
getRect
(
find
.
byKey
(
const
Key
(
'Item 1'
))),
const
Rect
.
fromLTRB
(
712
,
20
,
760
,
560
));
expect
(
tester
.
getRect
(
find
.
byKey
(
const
Key
(
'Item 4'
))),
const
Rect
.
fromLTRB
(
568
,
20
,
616
,
560
));
// // Horizontal Footer, reversed
await
tester
.
pumpWidget
(
build
(
padding:
padding
,
footer:
horizontalFooter
,
scrollDirection:
Axis
.
horizontal
,
reverse:
true
));
expect
(
tester
.
getRect
(
find
.
byKey
(
footerKey
)),
const
Rect
.
fromLTRB
(
568
,
20
,
578
,
560
));
expect
(
tester
.
getRect
(
find
.
byKey
(
const
Key
(
'Item 1'
))),
const
Rect
.
fromLTRB
(
722
,
20
,
770
,
560
));
expect
(
tester
.
getRect
(
find
.
byKey
(
const
Key
(
'Item 4'
))),
const
Rect
.
fromLTRB
(
578
,
20
,
626
,
560
));
});
});
...
...
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