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

使用GetStorage保存Reorderable Grid后重启应用出现灰屏问题求助

解决Reorderable Grid排序状态保存后重启灰屏的问题

看起来你遇到的问题是虽然GetStorage保存和读取的列表数据都正确,但重启应用后界面显示灰屏。我帮你分析了代码,发现几个可能的问题,下面是修复方案:

问题分析

  1. State成员变量初始化时机问题:你在State类的成员变量中直接读取GetStorage,虽然main函数里已经await GetStorage.init(),但State成员变量的初始化早于initState调用,极端情况下可能出现GetStorage还未完全就绪的情况,导致读取的数据引发后续UI构建的隐性问题。
  2. setState使用不当:你把GetStorage的读写操作放在了setState的回调函数里,setState的作用是通知Flutter框架更新UI,里面应该只包含修改状态变量的代码,持久化操作不需要放在这里,这可能导致UI更新逻辑和数据持久化逻辑耦合,引发不可预期的问题。
  3. 潜在的资源加载问题:如果重启后读取的列表中的某个path对应的SVG资源不存在,会导致SvgPicture.asset加载失败,进而引发整个Grid崩溃,表现为灰屏。

修复后的完整代码

import "package:flutter/material.dart";
import "package:reorderable_grid_view/reorderable_grid_view.dart";
import "package:flutter_svg/flutter_svg.dart";
import "package:get/get.dart";
import "package:get_storage/get_storage.dart";

void main() async {
  await GetStorage.init();
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final box = GetStorage();
  late List<String> imagePaths;

  @override
  void initState() {
    super.initState();
    // 在initState中读取存储,确保GetStorage已完全初始化
    imagePaths = box.read('imagePaths') ?? [
      'remote',
      'timelapse',
      'video',
      'hdr',
      'star',
      'lightning',
      'drop',
      'vibrate',
    ];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ReorderableGridView.count(
        crossAxisCount: 2,
        childAspectRatio: 1,
        children: imagePaths
            .map((String path) => Card(
                  key: ValueKey(path),
                  child: Container(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        Text(path),
                        // 给SvgPicture添加错误处理,避免资源加载失败导致整个界面崩溃
                        SvgPicture.asset(
                          'assets/$path.svg',
                          color: Colors.red,
                          placeholderBuilder: (context) => const Icon(Icons.image_not_supported),
                          errorWidget: (context, url, error) => const Icon(Icons.error),
                        ),
                      ],
                    ),
                  ),
                ))
            .toList(),
        onReorder: (oldIndex, newIndex) {
          // 先修改列表数据
          String path = imagePaths.removeAt(oldIndex);
          imagePaths.insert(newIndex, path);
          // 更新UI
          setState(() {});
          // 持久化数据,不需要放在setState里
          box.write('imagePaths', imagePaths);
          // 显示提示
          Get.snackbar(
            '保存成功',
            '当前列表顺序已保存',
            snackPosition: SnackPosition.BOTTOM,
          );
          // 可以验证读取结果
          Get.snackbar(
            '读取存储的列表:',
            '${box.read('imagePaths').toString()}',
            snackPosition: SnackPosition.BOTTOM,
          );
        },
      ),
    );
  }
}

关键修改点说明

  • 将GetStorage读取移到initState:确保在State完全初始化后再读取存储,避免初始化时机问题。
  • 分离UI更新和数据持久化:setState只负责通知UI更新,GetStorage的写入操作放在外面,逻辑更清晰,避免耦合问题。
  • 添加SVG加载错误处理:通过placeholderBuilder和errorWidget处理SVG资源加载失败的情况,即使某个资源不存在,也不会导致整个界面崩溃,而是显示错误图标,方便排查问题。
  • 优化Snackbar提示:简化提示内容,避免重复打印列表(如果需要调试可以保留,但正式场景建议简化)。

另外,建议你检查assets文件夹下的所有SVG文件是否存在,路径是否和列表中的path完全匹配(比如大小写、文件名拼写),这也是导致灰屏的常见原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 19:17:31