字
字节笔记本
2026年2月22日
Flutter 拖拽列表实现:ReorderableListView 到自定义拖拽
API中转
¥120
Flutter 中实现拖拽列表的几种方式,从官方组件到自定义实现。
一、官方方案:ReorderableListView
最简单的方式,官方组件直接支持拖拽排序:
dart
class DragListPage extends StatefulWidget {
@override
State<DragListPage> createState() => _DragListPageState();
}
class _DragListPageState extends State<DragListPage> {
final List<String> _items = ['Item 1', 'Item 2', 'Item 3', 'Item 4'];
@override
Widget build(BuildContext context) {
return Scaffold(
body: ReorderableListView(
onReorder: (oldIndex, newIndex) {
setState(() {
if (newIndex > oldIndex) newIndex--;
final item = _items.removeAt(oldIndex);
_items.insert(newIndex, item);
});
},
children: _items.map((item) => ListTile(
key: ValueKey(item), // key 必须要有
title: Text(item),
trailing: const Icon(Icons.drag_handle),
)).toList(),
),
);
}
}注意:
onReorder里newIndex > oldIndex时要先-1,这是官方的一个小坑。
二、自定义拖拽样式
用 ReorderableListView.builder + proxyDecorator 控制拖拽时的外观:
dart
ReorderableListView.builder(
proxyDecorator: (child, index, animation) {
return Material(
elevation: 8,
borderRadius: BorderRadius.circular(8),
child: child,
);
},
itemCount: _items.length,
itemBuilder: (context, index) {
return ListTile(
key: ValueKey(_items[index]),
title: Text(_items[index]),
);
},
onReorder: (oldIndex, newIndex) {
setState(() {
if (newIndex > oldIndex) newIndex--;
final item = _items.removeAt(oldIndex);
_items.insert(newIndex, item);
});
},
)三、第三方库
flutter_reorderable_list
需要更复杂的交互(如跨列表拖拽):
yaml
dependencies:
flutter_reorderable_list: ^1.0.0reorderable_grid_view
支持 Grid 拖拽:
yaml
dependencies:
reorderable_grid_view: ^2.0.0四、跨列表拖拽(高级)
用 Flutter 原生的 Draggable + DragTarget 组合实现:
dart
// 拖拽源
Draggable<String>(
data: item,
feedback: Material(
child: Text(item), // 拖拽时跟随手指的 widget
),
childWhenDragging: Opacity(
opacity: 0.3,
child: Text(item), // 原位置变透明
),
child: Text(item),
)
// 放置目标
DragTarget<String>(
onAccept: (data) {
// data 就是拖过来的数据
setState(() { /* 更新列表 */ });
},
builder: (context, candidateData, rejectedData) {
return Container(
color: candidateData.isNotEmpty ? Colors.blue[100] : Colors.white,
child: Text('放这里'),
);
},
)选择建议
| 场景 | 方案 |
|---|---|
| 单列表排序 | ReorderableListView,够用且简单 |
| 自定义拖拽 UI | ReorderableListView + proxyDecorator |
| Grid 拖拽 | reorderable_grid_view |
| 跨列表 / 跨区域拖拽 | Draggable + DragTarget 手动实现 |
总结
Flutter 拖拽列表的实现方式:
- 简单场景:直接用
ReorderableListView - 自定义样式:
proxyDecorator控制拖拽外观 - 复杂交互:第三方库或原生
Draggable+DragTarget
根据需求选择合适方案,大部分场景官方组件已足够。
分享: