Skip to content

Commit e2ef38d

Browse files
authored
Maintain the same layout constraints for item in the ReorderableList during dragging as before dragging. (#147863)
Fixes #147419
1 parent 4ecc1b0 commit e2ef38d

File tree

2 files changed

+65
-5
lines changed

2 files changed

+65
-5
lines changed

packages/flutter/lib/src/widgets/reorderable_list.dart

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import 'basic.dart';
1111
import 'debug.dart';
1212
import 'framework.dart';
1313
import 'inherited_theme.dart';
14+
import 'layout_builder.dart';
1415
import 'localizations.dart';
1516
import 'media_query.dart';
1617
import 'overlay.dart';
@@ -1083,6 +1084,8 @@ class _ReorderableItemState extends State<_ReorderableItem> {
10831084
}
10841085
}
10851086
bool _dragging = false;
1087+
BoxConstraints? get childLayoutConstraints => _childLayoutConstraints;
1088+
BoxConstraints? _childLayoutConstraints;
10861089

10871090
@override
10881091
void initState() {
@@ -1114,10 +1117,13 @@ class _ReorderableItemState extends State<_ReorderableItem> {
11141117
return SizedBox.fromSize(size: size);
11151118
}
11161119
_listState._registerItem(this);
1117-
return Transform(
1118-
transform: Matrix4.translationValues(offset.dx, offset.dy, 0.0),
1119-
child: widget.child,
1120-
);
1120+
return LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
1121+
_childLayoutConstraints = constraints;
1122+
return Transform(
1123+
transform: Matrix4.translationValues(offset.dx, offset.dy, 0.0),
1124+
child: widget.child,
1125+
);
1126+
});
11211127
}
11221128

11231129
@override
@@ -1337,6 +1343,7 @@ class _DragInfo extends Drag {
13371343
dragOffset = itemRenderBox.globalToLocal(initialPosition);
13381344
itemSize = item.context.size!;
13391345
itemExtent = _sizeExtent(itemSize, scrollDirection);
1346+
itemLayoutConstraints = item.childLayoutConstraints!;
13401347
scrollable = Scrollable.of(item.context);
13411348
}
13421349

@@ -1354,6 +1361,7 @@ class _DragInfo extends Drag {
13541361
late Offset dragPosition;
13551362
late Offset dragOffset;
13561363
late Size itemSize;
1364+
late BoxConstraints itemLayoutConstraints;
13571365
late double itemExtent;
13581366
late CapturedThemes capturedThemes;
13591367
ScrollableState? scrollable;
@@ -1411,6 +1419,7 @@ class _DragInfo extends Drag {
14111419
listState: listState,
14121420
index: index,
14131421
size: itemSize,
1422+
constraints: itemLayoutConstraints,
14141423
animation: _proxyAnimation!,
14151424
position: dragPosition - dragOffset - _overlayOrigin(context),
14161425
proxyDecorator: proxyDecorator,
@@ -1433,6 +1442,7 @@ class _DragItemProxy extends StatelessWidget {
14331442
required this.child,
14341443
required this.position,
14351444
required this.size,
1445+
required this.constraints,
14361446
required this.animation,
14371447
required this.proxyDecorator,
14381448
});
@@ -1442,6 +1452,7 @@ class _DragItemProxy extends StatelessWidget {
14421452
final Widget child;
14431453
final Offset position;
14441454
final Size size;
1455+
final BoxConstraints constraints;
14451456
final AnimationController animation;
14461457
final ReorderItemProxyDecorator? proxyDecorator;
14471458

@@ -1468,7 +1479,14 @@ class _DragItemProxy extends StatelessWidget {
14681479
child: SizedBox(
14691480
width: size.width,
14701481
height: size.height,
1471-
child: child,
1482+
child: OverflowBox(
1483+
minWidth: constraints.minWidth,
1484+
minHeight: constraints.minHeight,
1485+
maxWidth: constraints.maxWidth,
1486+
maxHeight: constraints.maxHeight,
1487+
alignment: listState._scrollDirection == Axis.horizontal ? Alignment.centerLeft : Alignment.topCenter,
1488+
child: child,
1489+
),
14721490
),
14731491
);
14741492
},

packages/flutter/test/widgets/reorderable_list_test.dart

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,6 +1528,48 @@ void main() {
15281528
await testFor(prototypeItem: const SizedBox(height: 100, width: 100, child: Text('prototype')));
15291529
await testFor(itemExtent: 100);
15301530
});
1531+
1532+
testWidgets('The item being dragged will not be affected by layout constraints.', (WidgetTester tester) async {
1533+
final Map<int, BoxConstraints> itemLayoutConstraints = <int, BoxConstraints>{};
1534+
await tester.pumpWidget(
1535+
MaterialApp(
1536+
home: Scaffold(
1537+
body: CustomScrollView(
1538+
slivers: <Widget>[
1539+
SliverReorderableList(
1540+
itemBuilder: (BuildContext context, int index) {
1541+
return LayoutBuilder(
1542+
key: ValueKey<int>(index),
1543+
builder: (BuildContext context, BoxConstraints constraints) {
1544+
itemLayoutConstraints[index] = constraints;
1545+
return SizedBox(
1546+
height: 100,
1547+
child: ReorderableDragStartListener(
1548+
index: index,
1549+
child: Text('$index'),
1550+
),
1551+
);
1552+
}
1553+
);
1554+
},
1555+
itemCount: 5,
1556+
onReorder: (int fromIndex, int toIndex) {},
1557+
),
1558+
],
1559+
),
1560+
),
1561+
),
1562+
);
1563+
final Map<int, BoxConstraints> preDragLayoutConstraints = Map<int, BoxConstraints>.of(itemLayoutConstraints);
1564+
itemLayoutConstraints.clear();
1565+
final TestGesture drag = await tester.startGesture(tester.getCenter(find.text('0')));
1566+
await tester.pump(kLongPressTimeout);
1567+
await drag.moveBy(const Offset(0, 20));
1568+
await tester.pump();
1569+
expect(itemLayoutConstraints, preDragLayoutConstraints);
1570+
await drag.up();
1571+
await tester.pumpAndSettle();
1572+
});
15311573
}
15321574

15331575
class TestList extends StatelessWidget {

0 commit comments

Comments
 (0)