mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Fixed a problem with the first drag update on a reorderable list. (#82296)
This commit is contained in:
parent
3445cb86f2
commit
7903370baa
@ -6,6 +6,7 @@ import 'dart:math';
|
||||
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
|
||||
import 'basic.dart';
|
||||
import 'debug.dart';
|
||||
@ -521,6 +522,15 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
|
||||
Offset? _finalDropPosition;
|
||||
MultiDragGestureRecognizer? _recognizer;
|
||||
bool _autoScrolling = false;
|
||||
// To implement the gap for the dragged item, we replace the dragged item
|
||||
// with a zero sized box, and then translate all of the later items down
|
||||
// by the size of the dragged item. This allows us to keep the order of the
|
||||
// list, while still being able to animate the gap between the items. However
|
||||
// for the first frame of the drag, the item has not yet been replaced, so
|
||||
// the calculation for the gap is off by the size of the gap. This flag is
|
||||
// used to determine if the transition to the zero sized box has completed,
|
||||
// so the gap calculation can compensate for it.
|
||||
bool _dragStartTransitionComplete = false;
|
||||
|
||||
late ScrollableState _scrollable;
|
||||
Axis get _scrollDirection => axisDirectionToAxis(_scrollable.axisDirection);
|
||||
@ -615,6 +625,10 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
|
||||
final _ReorderableItemState item = _items[_dragIndex!]!;
|
||||
item.dragging = true;
|
||||
item.rebuild();
|
||||
_dragStartTransitionComplete = false;
|
||||
SchedulerBinding.instance!.addPostFrameCallback((Duration duration) {
|
||||
_dragStartTransitionComplete = true;
|
||||
});
|
||||
|
||||
_insertIndex = item.index;
|
||||
_dragInfo = _DragInfo(
|
||||
@ -722,7 +736,14 @@ class SliverReorderableListState extends State<SliverReorderableList> with Ticke
|
||||
if (item.index == _dragIndex! || !item.mounted)
|
||||
continue;
|
||||
|
||||
final Rect geometry = item.targetGeometry();
|
||||
Rect geometry = item.targetGeometry();
|
||||
if (!_dragStartTransitionComplete && _dragIndex! <= item.index) {
|
||||
// Transition is not complete, so each item after the dragged item is still
|
||||
// in its normal location and not moved up for the zero sized box that will
|
||||
// replace the dragged item.
|
||||
final Offset transitionOffset = _extentOffset(_reverse ? -gapExtent : gapExtent, _scrollDirection);
|
||||
geometry = (geometry.topLeft - transitionOffset) & geometry.size;
|
||||
}
|
||||
final double itemStart = _scrollDirection == Axis.vertical ? geometry.top : geometry.left;
|
||||
final double itemExtent = _scrollDirection == Axis.vertical ? geometry.height : geometry.width;
|
||||
final double itemEnd = itemStart + itemExtent;
|
||||
|
||||
@ -122,7 +122,7 @@ void main() {
|
||||
expect(items, orderedEquals(<int>[0, 1, 2, 3, 4, 5, 6, 7]));
|
||||
|
||||
// Drag item 0 downwards more than halfway to displace item 1.
|
||||
await pressDragRelease(tester.getCenter(find.text('item 0')), const Offset(0, 151));
|
||||
await pressDragRelease(tester.getCenter(find.text('item 0')), const Offset(0, 51));
|
||||
check(visible: <int>[0, 1, 2, 3, 4, 5], hidden: <int>[6, 7]);
|
||||
expect(tester.getTopLeft(find.text('item 1')), Offset.zero);
|
||||
expect(tester.getTopLeft(find.text('item 0')), const Offset(0, 100));
|
||||
@ -136,7 +136,7 @@ void main() {
|
||||
expect(items, orderedEquals(<int>[0, 1, 2, 3, 4, 5, 6, 7]));
|
||||
|
||||
// Drag item 1 to item 3
|
||||
await pressDragRelease(tester.getCenter(find.text('item 1')), const Offset(0, 251));
|
||||
await pressDragRelease(tester.getCenter(find.text('item 1')), const Offset(0, 151));
|
||||
check(visible: <int>[0, 1, 2, 3, 4, 5], hidden: <int>[6, 7]);
|
||||
expect(tester.getTopLeft(find.text('item 0')), Offset.zero);
|
||||
expect(tester.getTopLeft(find.text('item 1')), const Offset(0, 300));
|
||||
@ -433,7 +433,7 @@ void main() {
|
||||
await tester.pump(kPressTimeout);
|
||||
|
||||
// Drag enough to move down the first item
|
||||
await drag.moveBy(const Offset(0, 150));
|
||||
await drag.moveBy(const Offset(0, 50));
|
||||
await tester.pump();
|
||||
await drag.up();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user