flutter / flutter/flutter

SliverReorderableList onReorder captures incorrect item height on web when setState called on drag start.

Open
#180,750 0 comments 0 reactions 0 assignees View on GitHub
framework P2 platform-web team-framework triaged-framework
Dominant language
Dart
Stars
179k
Forks
31.1k
PR merge metrics
PR metrics pending

Description

### Steps to reproduce

1. Create a ```SliverReorderableList()``` with items that have dynamic heights.
2. In ```onReorderStart``` callback, change item heights.
3. Start dragging an item.
4. Observe on web vs native platforms. On web the height of the 'ghost' item being dragegd doesn't change. When tested on ios it does change.

### Expected results

All items in the list change to the new height, including the 'ghost' snapshot of the item being dragged.

### Actual results

All items in the list change to the new height, except from the 'ghost' snapshot of the item being dragged, which retains the old height.

### Code sample

Code sample

```dart
import 'package:flutter/material.dart';

void main() => runApp(const ReorderableSliverListExample());

class ReorderableSliverListExample extends StatefulWidget {
const ReorderableSliverListExample({super.key});

@override
State createState() =>
_ReorderableSliverListExampleState();
}

class _ReorderableSliverListExampleState
extends State {
late List childrenSizes;
static const double bigSize = 100;
static const double smallSize = 50;

@override
void initState() {
super.initState();
childrenSizes = List.generate(10, (_) => bigSize);
}

void collapseAll() {
setState(() {
for (int i = 0; i < childrenSizes.length; i++) {
childrenSizes[i] = smallSize;
}
});
}

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: CustomScrollView(
slivers: [
SliverReorderableList(
itemBuilder: (context, index) => KeyedSubtree(
key: ValueKey(index),
child: ReorderableDragStartListener(
index: index,
child: Container(
color: Colors.green[100],
height: childrenSizes[index],
child: Text('Item $index'),
),
),
),
itemCount: 10,
onReorderStart: (index) => collapseAll(),
onReorder: (oldIndex, newIndex) {
if (oldIndex < newIndex) newIndex -= 1;
final item = childrenSizes.removeAt(oldIndex);
childrenSizes.insert(newIndex, item);
},
),
],
),
),
);
}
}

```

### Screenshots or Video

Screenshots / Video demonstration

https://github.com/user-attachments/assets/3077d96f-a445-4498-8d01-b66686a1adc5

### Logs

Logs

Not applicable.

### Flutter Doctor output

Doctor output

```console
Doctor summary (to see all details, run flutter doctor -v):
[!] Flutter (Channel stable, 3.38.6, on macOS 15.4.1 24E263 darwin-x64, locale en-GB)
! Warning: `flutter` on your path resolves to
/bin/flutter, which is not inside your current
Flutter SDK checkout at /flutter. Consider adding
/flutter/bin to the front of your path.
! Warning: `dart` on your path resolves to
/flutter/bin/dart, which is not inside your current
Flutter SDK checkout at /flutter. Consider adding
/flutter/bin to the front of your path.
[!] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
✗ Flutter requires Android SDK 36 and the Android BuildTools 28.0.3
To update the Android SDK visit https://flutter.dev/to/macos-android-setup for detailed instructions.
! Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses
[!] Xcode - develop for iOS and macOS (Xcode 16.4)
! CocoaPods 1.15.2 out of date (1.16.2 is recommended).
CocoaPods is a package manager for iOS or macOS platform code.
Without CocoaPods, plugins will not work on iOS or macOS.
For more info, see https://flutter.dev/to/platform-plugins
To update CocoaPods, see https://guides.cocoapods.org/using/getting-started.html#updating-cocoapods
[✓] Chrome - develop for the web
[✓] Connected device (3 available)
[✓] Network resources

! Doctor found issues in 3 categories.
```

Contributor guide

Open the contributing guide

Research direction

Start with the SliverReorderableList entry point and reproduce the supplied example, comparing web with iOS after onReorderStart calls setState. Trace how the dragged item's ghost snapshot gets its height; done means the ghost updates to the new item height on web as it does on native platforms.

Written by the indexing model from the issue text.

Assessment

Tech stack
dart, flutter
Domain
frontend, web-dev
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.