You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter 3.x中ReorderableListView无法拖动排序问题排查

问题:ReorderableListView无法拖动排序

我尝试在Flutter应用中实现ReorderableListView,编写了如下代码:

import 'package:flutter/material.dart';

void main() => runApp(const MaterialApp(home: MyHomePage()));

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  void _onReorder(int oldIndex, int newIndex) => setState(
        () => items.insert(
          newIndex > oldIndex ? newIndex -= 1 : newIndex,
          items.removeAt(oldIndex),
        ),
      );

  var items = ['Item A', 'Item B', 'Item C'];

  @override
  Widget build(context) => Scaffold(
        body: ReorderableListView(
          onReorder: _onReorder,
          children: items.map((item) {
            var index = items.indexOf(item);
            return ListTile(
              key: Key('$index'),
              tileColor: Colors.white,
              title: Text(item),
              onTap: () {
                // Handle tap
              },
            );
          }).toList(),
        ),
      );
}

但列表项无法拖动排序,功能无法正常工作。我的Flutter版本信息为:

Flutter 3.3.8 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 52b3dc25f6 (3 days ago) • 2022-11-09 12:09:26 +0800
Engine • revision 857bd6b74c
Tools • Dart 2.18.4 • DevTools 2.15.0

执行flutter doctor检测结果无异常:

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.3.8, on macOS 13.0.1 22A400 darwin-x64, locale en-ID)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 14.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.3)
[✓] IntelliJ IDEA Ultimate Edition (version 2022.2.1)
[✓] VS Code (version 1.73.1)
[✓] Connected device (4 available)
[✓] HTTP Host Availability

• No issues found!

请问我的代码存在什么问题?


问题原因及修复方案

你的代码核心问题是列表项的Key设置错误:

  1. 使用items.indexOf(item)获取索引生成Key,当列表项排序后,indexOf返回的是元素在新数组中的位置,导致Key和列表项的实际位置不匹配,ReorderableListView无法正确识别可拖动项。
  2. 直接用索引作为Key本身就不稳定,排序后索引对应的元素会变化,违背了Key唯一标识Widget的设计初衷。

修复后的代码

import 'package:flutter/material.dart';

void main() => runApp(const MaterialApp(home: MyHomePage()));

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  void _onReorder(int oldIndex, int newIndex) => setState(
        () {
          if (newIndex > oldIndex) {
            newIndex -= 1;
          }
          final item = items.removeAt(oldIndex);
          items.insert(newIndex, item);
        },
      );

  var items = ['Item A', 'Item B', 'Item C'];

  @override
  Widget build(context) => Scaffold(
        body: ReorderableListView(
          onReorder: _onReorder,
          children: items.map((item) {
            // 用列表项的唯一内容作为Key,确保标识稳定
            return ListTile(
              key: Key(item),
              tileColor: Colors.white,
              title: Text(item),
              onTap: () {
                // Handle tap
              },
            );
          }).toList(),
        ),
      );
}

关键修复点

  • 将Key从基于索引改为基于列表项的内容(因为你的每个item都是唯一的),保证Key的唯一性和稳定性,不会随排序变化而混乱。
  • 调整了_onReorder的代码结构,逻辑不变但可读性更强,避免一行代码嵌套过多的问题。

内容的提问来源于stack exchange,提问作者Dika

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 10:30:52