Skip to content

Commit

Permalink
Maintain the same layout constraints for item in the ReorderableList …
Browse files Browse the repository at this point in the history
…during dragging as before dragging. (#147863)

Fixes #147419
  • Loading branch information
yiiim authored May 14, 2024
1 parent 4ecc1b0 commit e2ef38d
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 5 deletions.
28 changes: 23 additions & 5 deletions packages/flutter/lib/src/widgets/reorderable_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import 'basic.dart';
import 'debug.dart';
import 'framework.dart';
import 'inherited_theme.dart';
import 'layout_builder.dart';
import 'localizations.dart';
import 'media_query.dart';
import 'overlay.dart';
Expand Down Expand Up @@ -1083,6 +1084,8 @@ class _ReorderableItemState extends State<_ReorderableItem> {
}
}
bool _dragging = false;
BoxConstraints? get childLayoutConstraints => _childLayoutConstraints;
BoxConstraints? _childLayoutConstraints;

@override
void initState() {
Expand Down Expand Up @@ -1114,10 +1117,13 @@ class _ReorderableItemState extends State<_ReorderableItem> {
return SizedBox.fromSize(size: size);
}
_listState._registerItem(this);
return Transform(
transform: Matrix4.translationValues(offset.dx, offset.dy, 0.0),
child: widget.child,
);
return LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
_childLayoutConstraints = constraints;
return Transform(
transform: Matrix4.translationValues(offset.dx, offset.dy, 0.0),
child: widget.child,
);
});
}

@override
Expand Down Expand Up @@ -1337,6 +1343,7 @@ class _DragInfo extends Drag {
dragOffset = itemRenderBox.globalToLocal(initialPosition);
itemSize = item.context.size!;
itemExtent = _sizeExtent(itemSize, scrollDirection);
itemLayoutConstraints = item.childLayoutConstraints!;
scrollable = Scrollable.of(item.context);
}

Expand All @@ -1354,6 +1361,7 @@ class _DragInfo extends Drag {
late Offset dragPosition;
late Offset dragOffset;
late Size itemSize;
late BoxConstraints itemLayoutConstraints;
late double itemExtent;
late CapturedThemes capturedThemes;
ScrollableState? scrollable;
Expand Down Expand Up @@ -1411,6 +1419,7 @@ class _DragInfo extends Drag {
listState: listState,
index: index,
size: itemSize,
constraints: itemLayoutConstraints,
animation: _proxyAnimation!,
position: dragPosition - dragOffset - _overlayOrigin(context),
proxyDecorator: proxyDecorator,
Expand All @@ -1433,6 +1442,7 @@ class _DragItemProxy extends StatelessWidget {
required this.child,
required this.position,
required this.size,
required this.constraints,
required this.animation,
required this.proxyDecorator,
});
Expand All @@ -1442,6 +1452,7 @@ class _DragItemProxy extends StatelessWidget {
final Widget child;
final Offset position;
final Size size;
final BoxConstraints constraints;
final AnimationController animation;
final ReorderItemProxyDecorator? proxyDecorator;

Expand All @@ -1468,7 +1479,14 @@ class _DragItemProxy extends StatelessWidget {
child: SizedBox(
width: size.width,
height: size.height,
child: child,
child: OverflowBox(
minWidth: constraints.minWidth,
minHeight: constraints.minHeight,
maxWidth: constraints.maxWidth,
maxHeight: constraints.maxHeight,
alignment: listState._scrollDirection == Axis.horizontal ? Alignment.centerLeft : Alignment.topCenter,
child: child,
),
),
);
},
Expand Down
42 changes: 42 additions & 0 deletions packages/flutter/test/widgets/reorderable_list_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1528,6 +1528,48 @@ void main() {
await testFor(prototypeItem: const SizedBox(height: 100, width: 100, child: Text('prototype')));
await testFor(itemExtent: 100);
});

testWidgets('The item being dragged will not be affected by layout constraints.', (WidgetTester tester) async {
final Map<int, BoxConstraints> itemLayoutConstraints = <int, BoxConstraints>{};
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: CustomScrollView(
slivers: <Widget>[
SliverReorderableList(
itemBuilder: (BuildContext context, int index) {
return LayoutBuilder(
key: ValueKey<int>(index),
builder: (BuildContext context, BoxConstraints constraints) {
itemLayoutConstraints[index] = constraints;
return SizedBox(
height: 100,
child: ReorderableDragStartListener(
index: index,
child: Text('$index'),
),
);
}
);
},
itemCount: 5,
onReorder: (int fromIndex, int toIndex) {},
),
],
),
),
),
);
final Map<int, BoxConstraints> preDragLayoutConstraints = Map<int, BoxConstraints>.of(itemLayoutConstraints);
itemLayoutConstraints.clear();
final TestGesture drag = await tester.startGesture(tester.getCenter(find.text('0')));
await tester.pump(kLongPressTimeout);
await drag.moveBy(const Offset(0, 20));
await tester.pump();
expect(itemLayoutConstraints, preDragLayoutConstraints);
await drag.up();
await tester.pumpAndSettle();
});
}

class TestList extends StatelessWidget {
Expand Down

0 comments on commit e2ef38d

Please sign in to comment.