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
922bbfee
Unverified
Commit
922bbfee
authored
Feb 23, 2022
by
Viren Khatri
Committed by
GitHub
Feb 23, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adds `onReorderStart` and `onReorderEnd` arguments to `ReorderableList`. (#96049)
parent
3e4a7c0d
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
259 additions
and
0 deletions
+259
-0
reorderable_list.dart
packages/flutter/lib/src/material/reorderable_list.dart
+12
-0
reorderable_list.dart
packages/flutter/lib/src/widgets/reorderable_list.dart
+42
-0
reorderable_list_test.dart
packages/flutter/test/material/reorderable_list_test.dart
+76
-0
reorderable_list_test.dart
packages/flutter/test/widgets/reorderable_list_test.dart
+129
-0
No files found.
packages/flutter/lib/src/material/reorderable_list.dart
View file @
922bbfee
...
@@ -64,6 +64,8 @@ class ReorderableListView extends StatefulWidget {
...
@@ -64,6 +64,8 @@ class ReorderableListView extends StatefulWidget {
Key
?
key
,
Key
?
key
,
required
List
<
Widget
>
children
,
required
List
<
Widget
>
children
,
required
this
.
onReorder
,
required
this
.
onReorder
,
this
.
onReorderStart
,
this
.
onReorderEnd
,
this
.
itemExtent
,
this
.
itemExtent
,
this
.
prototypeItem
,
this
.
prototypeItem
,
this
.
proxyDecorator
,
this
.
proxyDecorator
,
...
@@ -131,6 +133,8 @@ class ReorderableListView extends StatefulWidget {
...
@@ -131,6 +133,8 @@ class ReorderableListView extends StatefulWidget {
required
this
.
itemBuilder
,
required
this
.
itemBuilder
,
required
this
.
itemCount
,
required
this
.
itemCount
,
required
this
.
onReorder
,
required
this
.
onReorder
,
this
.
onReorderStart
,
this
.
onReorderEnd
,
this
.
itemExtent
,
this
.
itemExtent
,
this
.
prototypeItem
,
this
.
prototypeItem
,
this
.
proxyDecorator
,
this
.
proxyDecorator
,
...
@@ -168,6 +172,12 @@ class ReorderableListView extends StatefulWidget {
...
@@ -168,6 +172,12 @@ class ReorderableListView extends StatefulWidget {
/// {@macro flutter.widgets.reorderable_list.onReorder}
/// {@macro flutter.widgets.reorderable_list.onReorder}
final
ReorderCallback
onReorder
;
final
ReorderCallback
onReorder
;
/// {@macro flutter.widgets.reorderable_list.onReorderStart}
final
void
Function
(
int
index
)?
onReorderStart
;
/// {@macro flutter.widgets.reorderable_list.onReorderEnd}
final
void
Function
(
int
index
)?
onReorderEnd
;
/// {@macro flutter.widgets.reorderable_list.proxyDecorator}
/// {@macro flutter.widgets.reorderable_list.proxyDecorator}
final
ReorderItemProxyDecorator
?
proxyDecorator
;
final
ReorderItemProxyDecorator
?
proxyDecorator
;
...
@@ -479,6 +489,8 @@ class _ReorderableListViewState extends State<ReorderableListView> {
...
@@ -479,6 +489,8 @@ class _ReorderableListViewState extends State<ReorderableListView> {
prototypeItem:
widget
.
prototypeItem
,
prototypeItem:
widget
.
prototypeItem
,
itemCount:
widget
.
itemCount
,
itemCount:
widget
.
itemCount
,
onReorder:
widget
.
onReorder
,
onReorder:
widget
.
onReorder
,
onReorderStart:
widget
.
onReorderStart
,
onReorderEnd:
widget
.
onReorderEnd
,
proxyDecorator:
widget
.
proxyDecorator
??
_proxyDecorator
,
proxyDecorator:
widget
.
proxyDecorator
??
_proxyDecorator
,
),
),
),
),
...
...
packages/flutter/lib/src/widgets/reorderable_list.dart
View file @
922bbfee
...
@@ -114,6 +114,8 @@ class ReorderableList extends StatefulWidget {
...
@@ -114,6 +114,8 @@ class ReorderableList extends StatefulWidget {
required
this
.
itemBuilder
,
required
this
.
itemBuilder
,
required
this
.
itemCount
,
required
this
.
itemCount
,
required
this
.
onReorder
,
required
this
.
onReorder
,
this
.
onReorderStart
,
this
.
onReorderEnd
,
this
.
itemExtent
,
this
.
itemExtent
,
this
.
prototypeItem
,
this
.
prototypeItem
,
this
.
proxyDecorator
,
this
.
proxyDecorator
,
...
@@ -166,6 +168,34 @@ class ReorderableList extends StatefulWidget {
...
@@ -166,6 +168,34 @@ class ReorderableList extends StatefulWidget {
/// {@endtemplate}
/// {@endtemplate}
final
ReorderCallback
onReorder
;
final
ReorderCallback
onReorder
;
/// {@template flutter.widgets.reorderable_list.onReorderStart}
/// A callback that is called when an item drag has started.
///
/// The index parameter of the callback is the index of the selected item.
///
/// See also:
///
/// * [onReorderEnd], which is a called when the dragged item is dropped.
/// * [onReorder], which reports that a list item has been dragged to a new
/// location.
/// {@endtemplate}
final
void
Function
(
int
index
)?
onReorderStart
;
/// {@template flutter.widgets.reorderable_list.onReorderEnd}
/// A callback that is called when the dragged item is dropped.
///
/// The index parameter of the callback is the index where the item is
/// dropped. Unlike [onReorder], this is called even when the list item is
/// dropped in the same location.
///
/// See also:
///
/// * [onReorderStart], which is a called when an item drag has started.
/// * [onReorder], which reports that a list item has been dragged to a new
/// location.
/// {@endtemplate}
final
void
Function
(
int
index
)?
onReorderEnd
;
/// {@template flutter.widgets.reorderable_list.proxyDecorator}
/// {@template flutter.widgets.reorderable_list.proxyDecorator}
/// A callback that allows the app to add an animated decoration around
/// A callback that allows the app to add an animated decoration around
/// an item when it is being dragged.
/// an item when it is being dragged.
...
@@ -360,6 +390,8 @@ class ReorderableListState extends State<ReorderableList> {
...
@@ -360,6 +390,8 @@ class ReorderableListState extends State<ReorderableList> {
itemBuilder:
widget
.
itemBuilder
,
itemBuilder:
widget
.
itemBuilder
,
itemCount:
widget
.
itemCount
,
itemCount:
widget
.
itemCount
,
onReorder:
widget
.
onReorder
,
onReorder:
widget
.
onReorder
,
onReorderStart:
widget
.
onReorderStart
,
onReorderEnd:
widget
.
onReorderEnd
,
proxyDecorator:
widget
.
proxyDecorator
,
proxyDecorator:
widget
.
proxyDecorator
,
),
),
),
),
...
@@ -400,6 +432,8 @@ class SliverReorderableList extends StatefulWidget {
...
@@ -400,6 +432,8 @@ class SliverReorderableList extends StatefulWidget {
required
this
.
itemBuilder
,
required
this
.
itemBuilder
,
required
this
.
itemCount
,
required
this
.
itemCount
,
required
this
.
onReorder
,
required
this
.
onReorder
,
this
.
onReorderStart
,
this
.
onReorderEnd
,
this
.
itemExtent
,
this
.
itemExtent
,
this
.
prototypeItem
,
this
.
prototypeItem
,
this
.
proxyDecorator
,
this
.
proxyDecorator
,
...
@@ -419,6 +453,12 @@ class SliverReorderableList extends StatefulWidget {
...
@@ -419,6 +453,12 @@ class SliverReorderableList extends StatefulWidget {
/// {@macro flutter.widgets.reorderable_list.onReorder}
/// {@macro flutter.widgets.reorderable_list.onReorder}
final
ReorderCallback
onReorder
;
final
ReorderCallback
onReorder
;
/// {@macro flutter.widgets.reorderable_list.onReorderStart}
final
void
Function
(
int
)?
onReorderStart
;
/// {@macro flutter.widgets.reorderable_list.onReorderEnd}
final
void
Function
(
int
)?
onReorderEnd
;
/// {@macro flutter.widgets.reorderable_list.proxyDecorator}
/// {@macro flutter.widgets.reorderable_list.proxyDecorator}
final
ReorderItemProxyDecorator
?
proxyDecorator
;
final
ReorderItemProxyDecorator
?
proxyDecorator
;
...
@@ -640,6 +680,7 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
...
@@ -640,6 +680,7 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
assert
(
_dragInfo
==
null
);
assert
(
_dragInfo
==
null
);
final
_ReorderableItemState
item
=
_items
[
_dragIndex
!]!;
final
_ReorderableItemState
item
=
_items
[
_dragIndex
!]!;
item
.
dragging
=
true
;
item
.
dragging
=
true
;
widget
.
onReorderStart
?.
call
(
_dragIndex
!);
item
.
rebuild
();
item
.
rebuild
();
_dragStartTransitionComplete
=
false
;
_dragStartTransitionComplete
=
false
;
SchedulerBinding
.
instance
.
addPostFrameCallback
((
Duration
duration
)
{
SchedulerBinding
.
instance
.
addPostFrameCallback
((
Duration
duration
)
{
...
@@ -702,6 +743,7 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
...
@@ -702,6 +743,7 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
}
}
}
}
});
});
widget
.
onReorderEnd
?.
call
(
_insertIndex
!);
}
}
void
_dropCompleted
()
{
void
_dropCompleted
()
{
...
...
packages/flutter/test/material/reorderable_list_test.dart
View file @
922bbfee
...
@@ -1470,6 +1470,82 @@ void main() {
...
@@ -1470,6 +1470,82 @@ void main() {
expect
(
items
.
take
(
8
),
orderedEquals
(<
int
>[
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
]));
expect
(
items
.
take
(
8
),
orderedEquals
(<
int
>[
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
]));
});
});
testWidgets
(
'ReorderableListView calls onReorderStart and onReorderEnd correctly'
,
(
WidgetTester
tester
)
async
{
final
List
<
int
>
items
=
List
<
int
>.
generate
(
8
,
(
int
index
)
=>
index
);
int
?
startIndex
,
endIndex
;
final
Finder
item0
=
find
.
textContaining
(
'item 0'
);
void
handleReorder
(
int
fromIndex
,
int
toIndex
)
{
if
(
toIndex
>
fromIndex
)
{
toIndex
-=
1
;
}
items
.
insert
(
toIndex
,
items
.
removeAt
(
fromIndex
));
}
await
tester
.
pumpWidget
(
MaterialApp
(
home:
ReorderableListView
.
builder
(
itemBuilder:
(
BuildContext
context
,
int
index
)
{
return
SizedBox
(
key:
ValueKey
<
int
>(
items
[
index
]),
height:
100
,
child:
ReorderableDragStartListener
(
index:
index
,
child:
Row
(
crossAxisAlignment:
CrossAxisAlignment
.
start
,
children:
<
Widget
>[
Text
(
'item
${items[index]}
'
),
],
),
),
);
},
itemCount:
items
.
length
,
onReorder:
handleReorder
,
onReorderStart:
(
int
index
)
{
startIndex
=
index
;
},
onReorderEnd:
(
int
index
)
{
endIndex
=
index
;
},
),
));
TestGesture
drag
=
await
tester
.
startGesture
(
tester
.
getCenter
(
item0
));
await
tester
.
pump
(
kPressTimeout
);
// Drag enough for move to start.
await
drag
.
moveBy
(
const
Offset
(
0
,
20
));
expect
(
startIndex
,
equals
(
0
));
expect
(
endIndex
,
isNull
);
// Move item0 from index 0 to index 3
await
drag
.
moveBy
(
const
Offset
(
0
,
300
));
await
tester
.
pumpAndSettle
();
await
drag
.
up
();
await
tester
.
pumpAndSettle
();
expect
(
endIndex
,
equals
(
3
));
startIndex
=
null
;
endIndex
=
null
;
drag
=
await
tester
.
startGesture
(
tester
.
getCenter
(
item0
));
await
tester
.
pump
(
kPressTimeout
);
// Drag enough for move to start.
await
drag
.
moveBy
(
const
Offset
(
0
,
20
));
expect
(
startIndex
,
equals
(
2
));
expect
(
endIndex
,
isNull
);
// Move item0 from index 2 to index 0
await
drag
.
moveBy
(
const
Offset
(
0
,
-
200
));
await
tester
.
pumpAndSettle
();
await
drag
.
up
();
await
tester
.
pumpAndSettle
();
expect
(
endIndex
,
equals
(
0
));
});
testWidgets
(
'ReorderableListView throws an error when key is not passed to its children'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'ReorderableListView throws an error when key is not passed to its children'
,
(
WidgetTester
tester
)
async
{
final
Widget
reorderableListView
=
ReorderableListView
.
builder
(
final
Widget
reorderableListView
=
ReorderableListView
.
builder
(
itemBuilder:
(
BuildContext
context
,
int
index
)
{
itemBuilder:
(
BuildContext
context
,
int
index
)
{
...
...
packages/flutter/test/widgets/reorderable_list_test.dart
View file @
922bbfee
...
@@ -467,6 +467,130 @@ void main() {
...
@@ -467,6 +467,130 @@ void main() {
expect
(
tester
.
getTopLeft
(
find
.
text
(
'item 0'
)),
const
Offset
(
0
,
500
));
expect
(
tester
.
getTopLeft
(
find
.
text
(
'item 0'
)),
const
Offset
(
0
,
500
));
});
});
testWidgets
(
'SliverReorderableList calls onReorderStart and onReorderEnd correctly'
,
(
WidgetTester
tester
)
async
{
final
List
<
int
>
items
=
List
<
int
>.
generate
(
8
,
(
int
index
)
=>
index
);
int
?
startIndex
,
endIndex
;
final
Finder
item0
=
find
.
textContaining
(
'item 0'
);
await
tester
.
pumpWidget
(
TestList
(
items:
items
,
onReorderStart:
(
int
index
)
{
startIndex
=
index
;
},
onReorderEnd:
(
int
index
)
{
endIndex
=
index
;
},
));
TestGesture
drag
=
await
tester
.
startGesture
(
tester
.
getCenter
(
item0
));
await
tester
.
pump
(
kPressTimeout
);
// Drag enough for move to start.
await
drag
.
moveBy
(
const
Offset
(
0
,
20
));
expect
(
startIndex
,
equals
(
0
));
expect
(
endIndex
,
isNull
);
// Move item0 from index 0 to index 3
await
drag
.
moveBy
(
const
Offset
(
0
,
300
));
await
tester
.
pumpAndSettle
();
await
drag
.
up
();
await
tester
.
pumpAndSettle
();
expect
(
endIndex
,
equals
(
3
));
startIndex
=
null
;
endIndex
=
null
;
drag
=
await
tester
.
startGesture
(
tester
.
getCenter
(
item0
));
await
tester
.
pump
(
kPressTimeout
);
// Drag enough for move to start.
await
drag
.
moveBy
(
const
Offset
(
0
,
20
));
expect
(
startIndex
,
equals
(
2
));
expect
(
endIndex
,
isNull
);
// Move item0 from index 2 to index 0
await
drag
.
moveBy
(
const
Offset
(
0
,
-
200
));
await
tester
.
pumpAndSettle
();
await
drag
.
up
();
await
tester
.
pumpAndSettle
();
expect
(
endIndex
,
equals
(
0
));
});
testWidgets
(
'ReorderableList calls onReorderStart and onReorderEnd correctly'
,
(
WidgetTester
tester
)
async
{
final
List
<
int
>
items
=
List
<
int
>.
generate
(
8
,
(
int
index
)
=>
index
);
int
?
startIndex
,
endIndex
;
final
Finder
item0
=
find
.
textContaining
(
'item 0'
);
void
handleReorder
(
int
fromIndex
,
int
toIndex
)
{
if
(
toIndex
>
fromIndex
)
{
toIndex
-=
1
;
}
items
.
insert
(
toIndex
,
items
.
removeAt
(
fromIndex
));
}
await
tester
.
pumpWidget
(
MaterialApp
(
home:
ReorderableList
(
itemCount:
items
.
length
,
itemBuilder:
(
BuildContext
context
,
int
index
)
{
return
SizedBox
(
key:
ValueKey
<
int
>(
items
[
index
]),
height:
100
,
child:
ReorderableDelayedDragStartListener
(
index:
index
,
child:
Text
(
'item
${items[index]}
'
),
),
);
},
onReorder:
handleReorder
,
onReorderStart:
(
int
index
)
{
startIndex
=
index
;
},
onReorderEnd:
(
int
index
)
{
endIndex
=
index
;
},
),
));
TestGesture
drag
=
await
tester
.
startGesture
(
tester
.
getCenter
(
item0
));
await
tester
.
pump
(
kLongPressTimeout
);
// Drag enough for move to start.
await
drag
.
moveBy
(
const
Offset
(
0
,
20
));
expect
(
startIndex
,
equals
(
0
));
expect
(
endIndex
,
isNull
);
// Move item0 from index 0 to index 3
await
drag
.
moveBy
(
const
Offset
(
0
,
300
));
await
tester
.
pumpAndSettle
();
await
drag
.
up
();
await
tester
.
pumpAndSettle
();
expect
(
endIndex
,
equals
(
3
));
startIndex
=
null
;
endIndex
=
null
;
drag
=
await
tester
.
startGesture
(
tester
.
getCenter
(
item0
));
await
tester
.
pump
(
kLongPressTimeout
);
// Drag enough for move to start.
await
drag
.
moveBy
(
const
Offset
(
0
,
20
));
expect
(
startIndex
,
equals
(
2
));
expect
(
endIndex
,
isNull
);
// Move item0 from index 2 to index 0
await
drag
.
moveBy
(
const
Offset
(
0
,
-
200
));
await
tester
.
pumpAndSettle
();
await
drag
.
up
();
await
tester
.
pumpAndSettle
();
expect
(
endIndex
,
equals
(
0
));
});
testWidgets
(
'ReorderableList asserts on both non-null itemExtent and prototypeItem'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'ReorderableList asserts on both non-null itemExtent and prototypeItem'
,
(
WidgetTester
tester
)
async
{
final
List
<
int
>
numbers
=
<
int
>[
0
,
1
,
2
];
final
List
<
int
>
numbers
=
<
int
>[
0
,
1
,
2
];
expect
(()
=>
ReorderableList
(
expect
(()
=>
ReorderableList
(
...
@@ -794,6 +918,8 @@ class TestList extends StatefulWidget {
...
@@ -794,6 +918,8 @@ class TestList extends StatefulWidget {
this
.
proxyDecorator
,
this
.
proxyDecorator
,
required
this
.
items
,
required
this
.
items
,
this
.
reverse
=
false
,
this
.
reverse
=
false
,
this
.
onReorderStart
,
this
.
onReorderEnd
,
})
:
super
(
key:
key
);
})
:
super
(
key:
key
);
final
List
<
int
>
items
;
final
List
<
int
>
items
;
...
@@ -801,6 +927,7 @@ class TestList extends StatefulWidget {
...
@@ -801,6 +927,7 @@ class TestList extends StatefulWidget {
final
Color
?
iconColor
;
final
Color
?
iconColor
;
final
ReorderItemProxyDecorator
?
proxyDecorator
;
final
ReorderItemProxyDecorator
?
proxyDecorator
;
final
bool
reverse
;
final
bool
reverse
;
final
void
Function
(
int
)?
onReorderStart
,
onReorderEnd
;
@override
@override
State
<
TestList
>
createState
()
=>
_TestListState
();
State
<
TestList
>
createState
()
=>
_TestListState
();
...
@@ -849,6 +976,8 @@ class _TestListState extends State<TestList> {
...
@@ -849,6 +976,8 @@ class _TestListState extends State<TestList> {
});
});
},
},
proxyDecorator:
widget
.
proxyDecorator
,
proxyDecorator:
widget
.
proxyDecorator
,
onReorderStart:
widget
.
onReorderStart
,
onReorderEnd:
widget
.
onReorderEnd
,
),
),
],
],
);
);
...
...
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