Flutter中如何保存ReorderableListView的排序状态?
解决ReorderableListView排序重启后不保留的问题
你当前的代码只是在内存中调整了tasks列表的顺序,重启应用后内存数据会被重置,自然恢复成初始状态。而PageStorage的作用是保存页面的滚动位置、展开状态这类UI状态,并不负责持久化业务数据,所以用它没用。
要解决这个问题,核心是把排序后的列表数据持久化到本地存储,重启时再从本地读取恢复。下面是具体实现步骤:
1. 选择持久化方案
根据数据量大小选合适的方案:
- 小数据量(比如几十条以内的简单列表):用
SharedPreferences最方便 - 复杂/大数据量:用Hive、SQLite或Isar这类数据库
下面以SharedPreferences为例演示。
2. 改造代码步骤
第一步:添加依赖
在pubspec.yaml里添加shared_preferences:
dependencies: flutter: sdk: flutter shared_preferences: ^2.2.2 # 可替换为最新版本
第二步:完整实现代码
import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'dart:convert'; class ReorderableListPage extends StatefulWidget { const ReorderableListPage({super.key}); @override State<ReorderableListPage> createState() => _ReorderableListPageState(); } class _ReorderableListPageState extends State<ReorderableListPage> { List<Map<String, dynamic>> tasks = []; @override void initState() { super.initState(); _loadTasks(); // 初始化时从本地读取数据 } // 从本地读取保存的任务列表 Future<void> _loadTasks() async { final prefs = await SharedPreferences.getInstance(); final tasksJson = prefs.getString('tasks'); if (tasksJson != null) { setState(() { tasks = List<Map<String, dynamic>>.from(jsonDecode(tasksJson)); }); } else { // 本地无数据时初始化默认列表 setState(() { tasks = [ {'name': '任务1'}, {'name': '任务2'}, {'name': '任务3'}, ]; }); } } // 将任务列表保存到本地 Future<void> _saveTasks() async { final prefs = await SharedPreferences.getInstance(); await prefs.setString('tasks', jsonEncode(tasks)); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('可拖拽排序列表')), body: ReorderableListView( physics: const ClampingScrollPhysics(), shrinkWrap: true, onReorder: (int oldIndex, int newIndex) { setState(() { if (newIndex > oldIndex) newIndex--; final item = tasks.removeAt(oldIndex); tasks.insert(newIndex, item); }); _saveTasks(); // 排序完成后立即保存到本地 }, children: [ for (final item in tasks) Container( key: ValueKey(item['name']), // 用唯一标识当key,避免Map类型key的不稳定问题 margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 16), child: ExpansionTile( title: Text(item['name']), ), ) ], ), ); } }
关键说明
_loadTasks:页面初始化时从SharedPreferences读取之前保存的列表,无本地数据则加载默认值_saveTasks:每次拖拽排序完成后,将新列表转成JSON字符串存入本地ValueKey优化:原来用ValueKey(item)(item为Map)可能导致key不稳定,改用item内唯一字段(如name)更可靠
3. 复杂数据场景处理
如果你的tasks是自定义对象(而非Map),需要先为对象实现序列化/反序列化逻辑,比如使用json_serializable生成toJson/fromJson方法,再进行存储和读取。
内容的提问来源于stack exchange,提问作者RitikaDesai
相关产品推荐
相关产品推荐

