Maintain the same layout constraints for item in the ReorderableList during dragging as before dragging. (#147863)

Fixes #147419
This commit is contained in:
yim 2024-05-15 04:52:59 +08:00 committed by GitHub
parent 4ecc1b092b
commit e2ef38d19f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 65 additions and 5 deletions

View File

@ -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';
@ -1083,6 +1084,8 @@ class _ReorderableItemState extends State<_ReorderableItem> {
}
}
bool _dragging = false;
BoxConstraints? get childLayoutConstraints => _childLayoutConstraints;
BoxConstraints? _childLayoutConstraints;
@override
void initState() {
@ -1114,10 +1117,13 @@ class _ReorderableItemState extends State<_ReorderableItem> {
return SizedBox.fromSize(size: size);
}
_listState._registerItem(this);
return LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
_childLayoutConstraints = constraints;
return Transform(
transform: Matrix4.translationValues(offset.dx, offset.dy, 0.0),
child: widget.child,
);
});
}
@override
@ -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);
}
@ -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;
@ -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,
@ -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,
});
@ -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;
@ -1468,8 +1479,15 @@ class _DragItemProxy extends StatelessWidget {
child: SizedBox(
width: size.width,
height: size.height,
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,
),
),
);
},
child: proxyChild,

View File

@ -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 {