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
635dfc3e
Unverified
Commit
635dfc3e
authored
Dec 09, 2020
by
gabber235
Committed by
GitHub
Dec 09, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Draggable: onDragUpdate callback (#68185)
parent
d12098da
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
177 additions
and
0 deletions
+177
-0
drag_target.dart
packages/flutter/lib/src/widgets/drag_target.dart
+25
-0
draggable_test.dart
packages/flutter/test/widgets/draggable_test.dart
+152
-0
No files found.
packages/flutter/lib/src/widgets/drag_target.dart
View file @
635dfc3e
...
@@ -36,6 +36,11 @@ typedef DragTargetAcceptWithDetails<T> = void Function(DragTargetDetails<T> deta
...
@@ -36,6 +36,11 @@ typedef DragTargetAcceptWithDetails<T> = void Function(DragTargetDetails<T> deta
/// Used by [DragTarget.builder].
/// Used by [DragTarget.builder].
typedef
DragTargetBuilder
<
T
>
=
Widget
Function
(
BuildContext
context
,
List
<
T
?>
candidateData
,
List
<
dynamic
>
rejectedData
);
typedef
DragTargetBuilder
<
T
>
=
Widget
Function
(
BuildContext
context
,
List
<
T
?>
candidateData
,
List
<
dynamic
>
rejectedData
);
/// Signature for when a [Draggable] is dragged across the screen.
///
/// Used by [Draggable.onDragUpdate].
typedef
DragUpdateCallback
=
void
Function
(
DragUpdateDetails
details
);
/// Signature for when a [Draggable] is dropped without being accepted by a [DragTarget].
/// Signature for when a [Draggable] is dropped without being accepted by a [DragTarget].
///
///
/// Used by [Draggable.onDraggableCanceled].
/// Used by [Draggable.onDraggableCanceled].
...
@@ -187,6 +192,7 @@ class Draggable<T extends Object> extends StatefulWidget {
...
@@ -187,6 +192,7 @@ class Draggable<T extends Object> extends StatefulWidget {
this
.
affinity
,
this
.
affinity
,
this
.
maxSimultaneousDrags
,
this
.
maxSimultaneousDrags
,
this
.
onDragStarted
,
this
.
onDragStarted
,
this
.
onDragUpdate
,
this
.
onDraggableCanceled
,
this
.
onDraggableCanceled
,
this
.
onDragEnd
,
this
.
onDragEnd
,
this
.
onDragCompleted
,
this
.
onDragCompleted
,
...
@@ -298,6 +304,12 @@ class Draggable<T extends Object> extends StatefulWidget {
...
@@ -298,6 +304,12 @@ class Draggable<T extends Object> extends StatefulWidget {
/// Called when the draggable starts being dragged.
/// Called when the draggable starts being dragged.
final
VoidCallback
?
onDragStarted
;
final
VoidCallback
?
onDragStarted
;
/// Called when the draggable is being dragged.
///
/// This function will only be called while this widget is still mounted to
/// the tree (i.e. [State.mounted] is true), and if this widget has actually moved.
final
DragUpdateCallback
?
onDragUpdate
;
/// Called when the draggable is dropped without being accepted by a [DragTarget].
/// Called when the draggable is dropped without being accepted by a [DragTarget].
///
///
/// This function might be called after this widget has been removed from the
/// This function might be called after this widget has been removed from the
...
@@ -374,6 +386,7 @@ class LongPressDraggable<T extends Object> extends Draggable<T> {
...
@@ -374,6 +386,7 @@ class LongPressDraggable<T extends Object> extends Draggable<T> {
DragAnchor
dragAnchor
=
DragAnchor
.
child
,
DragAnchor
dragAnchor
=
DragAnchor
.
child
,
int
?
maxSimultaneousDrags
,
int
?
maxSimultaneousDrags
,
VoidCallback
?
onDragStarted
,
VoidCallback
?
onDragStarted
,
DragUpdateCallback
?
onDragUpdate
,
DraggableCanceledCallback
?
onDraggableCanceled
,
DraggableCanceledCallback
?
onDraggableCanceled
,
DragEndCallback
?
onDragEnd
,
DragEndCallback
?
onDragEnd
,
VoidCallback
?
onDragCompleted
,
VoidCallback
?
onDragCompleted
,
...
@@ -390,6 +403,7 @@ class LongPressDraggable<T extends Object> extends Draggable<T> {
...
@@ -390,6 +403,7 @@ class LongPressDraggable<T extends Object> extends Draggable<T> {
dragAnchor:
dragAnchor
,
dragAnchor:
dragAnchor
,
maxSimultaneousDrags:
maxSimultaneousDrags
,
maxSimultaneousDrags:
maxSimultaneousDrags
,
onDragStarted:
onDragStarted
,
onDragStarted:
onDragStarted
,
onDragUpdate:
onDragUpdate
,
onDraggableCanceled:
onDraggableCanceled
,
onDraggableCanceled:
onDraggableCanceled
,
onDragEnd:
onDragEnd
,
onDragEnd:
onDragEnd
,
onDragCompleted:
onDragCompleted
,
onDragCompleted:
onDragCompleted
,
...
@@ -474,6 +488,11 @@ class _DraggableState<T extends Object> extends State<Draggable<T>> {
...
@@ -474,6 +488,11 @@ class _DraggableState<T extends Object> extends State<Draggable<T>> {
feedback:
widget
.
feedback
,
feedback:
widget
.
feedback
,
feedbackOffset:
widget
.
feedbackOffset
,
feedbackOffset:
widget
.
feedbackOffset
,
ignoringFeedbackSemantics:
widget
.
ignoringFeedbackSemantics
,
ignoringFeedbackSemantics:
widget
.
ignoringFeedbackSemantics
,
onDragUpdate:
(
DragUpdateDetails
details
)
{
if
(
mounted
&&
widget
.
onDragUpdate
!=
null
)
{
widget
.
onDragUpdate
!(
details
);
}
},
onDragEnd:
(
Velocity
velocity
,
Offset
offset
,
bool
wasAccepted
)
{
onDragEnd:
(
Velocity
velocity
,
Offset
offset
,
bool
wasAccepted
)
{
if
(
mounted
)
{
if
(
mounted
)
{
setState
(()
{
setState
(()
{
...
@@ -708,6 +727,7 @@ class _DragAvatar<T extends Object> extends Drag {
...
@@ -708,6 +727,7 @@ class _DragAvatar<T extends Object> extends Drag {
this
.
dragStartPoint
=
Offset
.
zero
,
this
.
dragStartPoint
=
Offset
.
zero
,
this
.
feedback
,
this
.
feedback
,
this
.
feedbackOffset
=
Offset
.
zero
,
this
.
feedbackOffset
=
Offset
.
zero
,
this
.
onDragUpdate
,
this
.
onDragEnd
,
this
.
onDragEnd
,
required
this
.
ignoringFeedbackSemantics
,
required
this
.
ignoringFeedbackSemantics
,
})
:
assert
(
overlayState
!=
null
),
})
:
assert
(
overlayState
!=
null
),
...
@@ -725,6 +745,7 @@ class _DragAvatar<T extends Object> extends Drag {
...
@@ -725,6 +745,7 @@ class _DragAvatar<T extends Object> extends Drag {
final
Offset
dragStartPoint
;
final
Offset
dragStartPoint
;
final
Widget
?
feedback
;
final
Widget
?
feedback
;
final
Offset
feedbackOffset
;
final
Offset
feedbackOffset
;
final
DragUpdateCallback
?
onDragUpdate
;
final
_OnDragEnd
?
onDragEnd
;
final
_OnDragEnd
?
onDragEnd
;
final
OverlayState
overlayState
;
final
OverlayState
overlayState
;
final
bool
ignoringFeedbackSemantics
;
final
bool
ignoringFeedbackSemantics
;
...
@@ -737,8 +758,12 @@ class _DragAvatar<T extends Object> extends Drag {
...
@@ -737,8 +758,12 @@ class _DragAvatar<T extends Object> extends Drag {
@override
@override
void
update
(
DragUpdateDetails
details
)
{
void
update
(
DragUpdateDetails
details
)
{
final
Offset
oldPosition
=
_position
;
_position
+=
_restrictAxis
(
details
.
delta
);
_position
+=
_restrictAxis
(
details
.
delta
);
updateDrag
(
_position
);
updateDrag
(
_position
);
if
(
onDragUpdate
!=
null
&&
_position
!=
oldPosition
)
{
onDragUpdate
!(
details
);
}
}
}
@override
@override
...
...
packages/flutter/test/widgets/draggable_test.dart
View file @
635dfc3e
...
@@ -840,6 +840,158 @@ void main() {
...
@@ -840,6 +840,158 @@ void main() {
});
});
});
});
group
(
'Drag and drop - onDragUpdate called if draggable moves along a set axis'
,
()
{
int
updated
=
0
;
Offset
dragDelta
=
Offset
.
zero
;
setUp
(()
{
updated
=
0
;
dragDelta
=
Offset
.
zero
;
});
Widget
build
()
{
return
MaterialApp
(
home:
Column
(
children:
<
Widget
>[
Draggable
<
int
>(
data:
1
,
child:
const
Text
(
'Source'
),
feedback:
const
Text
(
'Dragging'
),
onDragUpdate:
(
DragUpdateDetails
details
)
{
dragDelta
+=
details
.
delta
;
updated
++;
},
),
Draggable
<
int
>(
data:
2
,
child:
const
Text
(
'Vertical Source'
),
feedback:
const
Text
(
'Vertical Dragging'
),
onDragUpdate:
(
DragUpdateDetails
details
)
{
dragDelta
+=
details
.
delta
;
updated
++;
},
axis:
Axis
.
vertical
,
),
Draggable
<
int
>(
data:
3
,
child:
const
Text
(
'Horizontal Source'
),
feedback:
const
Text
(
'Horizontal Dragging'
),
onDragUpdate:
(
DragUpdateDetails
details
)
{
dragDelta
+=
details
.
delta
;
updated
++;
},
axis:
Axis
.
horizontal
,
),
],
),
);
}
testWidgets
(
'Null axis onDragUpdate called only if draggable moves in any direction'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
build
());
expect
(
updated
,
0
);
expect
(
find
.
text
(
'Source'
),
findsOneWidget
);
expect
(
find
.
text
(
'Dragging'
),
findsNothing
);
final
Offset
firstLocation
=
tester
.
getCenter
(
find
.
text
(
'Source'
));
final
TestGesture
gesture
=
await
tester
.
startGesture
(
firstLocation
,
pointer:
7
);
await
tester
.
pump
();
expect
(
updated
,
0
);
expect
(
find
.
text
(
'Source'
),
findsOneWidget
);
expect
(
find
.
text
(
'Dragging'
),
findsOneWidget
);
await
gesture
.
moveBy
(
const
Offset
(
10
,
10
));
await
tester
.
pump
();
expect
(
updated
,
1
);
await
gesture
.
moveBy
(
Offset
.
zero
);
await
tester
.
pump
();
expect
(
updated
,
1
);
await
gesture
.
up
();
await
tester
.
pump
();
expect
(
updated
,
1
);
expect
(
find
.
text
(
'Source'
),
findsOneWidget
);
expect
(
find
.
text
(
'Dragging'
),
findsNothing
);
expect
(
dragDelta
.
dx
,
10
);
expect
(
dragDelta
.
dy
,
10
);
});
testWidgets
(
'Vertical axis onDragUpdate only called if draggable moves vertical'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
build
());
expect
(
updated
,
0
);
expect
(
find
.
text
(
'Vertical Source'
),
findsOneWidget
);
expect
(
find
.
text
(
'Vertical Dragging'
),
findsNothing
);
final
Offset
firstLocation
=
tester
.
getCenter
(
find
.
text
(
'Vertical Source'
));
final
TestGesture
gesture
=
await
tester
.
startGesture
(
firstLocation
,
pointer:
7
);
await
tester
.
pump
();
expect
(
updated
,
0
);
expect
(
find
.
text
(
'Vertical Source'
),
findsOneWidget
);
expect
(
find
.
text
(
'Vertical Dragging'
),
findsOneWidget
);
await
gesture
.
moveBy
(
const
Offset
(
0
,
10
));
await
tester
.
pump
();
expect
(
updated
,
1
);
await
gesture
.
moveBy
(
const
Offset
(
10
,
0
));
await
tester
.
pump
();
expect
(
updated
,
1
);
await
gesture
.
up
();
await
tester
.
pump
();
expect
(
updated
,
1
);
expect
(
find
.
text
(
'Vertical Source'
),
findsOneWidget
);
expect
(
find
.
text
(
'Vertical Dragging'
),
findsNothing
);
expect
(
dragDelta
.
dx
,
0
);
expect
(
dragDelta
.
dy
,
10
);
});
testWidgets
(
'Horizontal axis onDragUpdate only called if draggable moves horizontal'
,
(
WidgetTester
tester
)
async
{
await
tester
.
pumpWidget
(
build
());
expect
(
updated
,
0
);
expect
(
find
.
text
(
'Horizontal Source'
),
findsOneWidget
);
expect
(
find
.
text
(
'Horizontal Dragging'
),
findsNothing
);
final
Offset
firstLocation
=
tester
.
getCenter
(
find
.
text
(
'Horizontal Source'
));
final
TestGesture
gesture
=
await
tester
.
startGesture
(
firstLocation
,
pointer:
7
);
await
tester
.
pump
();
expect
(
updated
,
0
);
expect
(
find
.
text
(
'Horizontal Source'
),
findsOneWidget
);
expect
(
find
.
text
(
'Horizontal Dragging'
),
findsOneWidget
);
await
gesture
.
moveBy
(
const
Offset
(
0
,
10
));
await
tester
.
pump
();
expect
(
updated
,
0
);
await
gesture
.
moveBy
(
const
Offset
(
10
,
0
));
await
tester
.
pump
();
expect
(
updated
,
1
);
await
gesture
.
up
();
await
tester
.
pump
();
expect
(
updated
,
1
);
expect
(
find
.
text
(
'Horizontal Source'
),
findsOneWidget
);
expect
(
find
.
text
(
'Horizontal Dragging'
),
findsNothing
);
expect
(
dragDelta
.
dx
,
10
);
expect
(
dragDelta
.
dy
,
0
);
});
});
testWidgets
(
'Drag and drop - onDraggableCanceled not called if dropped on accepting target'
,
(
WidgetTester
tester
)
async
{
testWidgets
(
'Drag and drop - onDraggableCanceled not called if dropped on accepting target'
,
(
WidgetTester
tester
)
async
{
final
List
<
int
>
accepted
=
<
int
>[];
final
List
<
int
>
accepted
=
<
int
>[];
...
...
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