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

GetX控制器late变量初始化报错:页面加载红屏问题求助

解决方案

问题根源

  1. late Map<String, double> dataMap1仅声明未初始化实例,异步加载完成前直接访问会触发未初始化错误;
  2. reportFunction中调用dataMap1.addAll()时,dataMap1本身是null,会导致空指针;
  3. 异步加载数据期间,UI直接渲染依赖未就绪的dataMap1,引发红屏。

方案一:使用GetX响应式变量(推荐)

修改控制器代码

import 'package:get/get.dart';
import 'package:hive/hive.dart';

class ReportScreenController extends GetxController{
  // 用RxMap创建响应式Map,初始化为空Map
  final RxMap<String, double> dataMap1 = <String, double>{}.obs;

  final Map<String, double> dataMap2 = {
    "ورزشی": 5,
    "خصوصی": 3,
    "اداری": 5,
    "دسته بندی نشده": 3,
  };

  @override
  Future<void> onInit() async {
    super.onInit();
    await reportFunction();
  }

  Future<void> reportFunction() async {
    var taskBox = await Hive.openBox('task');
    var taskFinish = taskBox.values.where((task) => task.status == true).toList();
    var taskUnFinish = taskBox.values.where((task) => task.status == false).toList();
    
    double finishedCount = taskFinish.length.toDouble();
    double unFinishedCount = taskUnFinish.length.toDouble();
    
    // 直接赋值给响应式Map,自动通知UI更新
    dataMap1.value = {
      'رو زمین مانده': unFinishedCount,
      'تکمیل شده': finishedCount,
    };
  }
}

修改视图代码

用Obx包裹依赖dataMap1的组件,监听数据变化,数据就绪后自动渲染:

class ReportScreen extends GetView<ReportScreenController> {
  const ReportScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        fit: StackFit.expand,
        children: [
          background(),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 15.0),
            child: Column(
              children: [
                const Text(':نمودار فعالیت', style: boldText),
                // 用Obx监听dataMap1变化,数据为空时显示加载组件
                Obx(() {
                  if (controller.dataMap1.isEmpty) {
                    return const CircularProgressIndicator(); // 加载中提示
                  }
                  return MyPieChart(dataMap: controller.dataMap1);
                }),
                const Text(':نمودار وظایف', style: boldText),
                MyPieChart(dataMap: controller.dataMap2),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

方案二:使用普通Map+手动更新UI

如果不想用响应式变量,也可以初始化dataMap1为空Map,加载完成后调用update()通知UI刷新:

修改控制器代码

import 'package:get/get.dart';
import 'package:hive/hive.dart';

class ReportScreenController extends GetxController{
  // 初始化空Map,无需late
  Map<String, double> dataMap1 = {};

  final Map<String, double> dataMap2 = {
    "ورزشی": 5,
    "خصوصی": 3,
    "اداری": 5,
    "دسته بندی نشده": 3,
  };

  @override
  Future<void> onInit() async {
    super.onInit();
    await reportFunction();
    update(); // 数据加载完成后通知UI更新
  }

  Future<void> reportFunction() async {
    var taskBox = await Hive.openBox('task');
    var taskFinish = taskBox.values.where((task) => task.status == true).toList();
    var taskUnFinish = taskBox.values.where((task) => task.status == false).toList();
    
    double finishedCount = taskFinish.length.toDouble();
    double unFinishedCount = taskUnFinish.length.toDouble();
    
    dataMap1 = {
      'رو زمین مانده': unFinishedCount,
      'تکمیل شده': finishedCount,
    };
  }
}

修改视图代码

用GetBuilder包裹组件,监听控制器的更新:

class ReportScreen extends GetView<ReportScreenController> {
  const ReportScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        fit: StackFit.expand,
        children: [
          background(),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 15.0),
            child: Column(
              children: [
                const Text(':نمودار فعالیت', style: boldText),
                GetBuilder<ReportScreenController>(
                  builder: (ctrl) {
                    if (ctrl.dataMap1.isEmpty) {
                      return const CircularProgressIndicator();
                    }
                    return MyPieChart(dataMap: ctrl.dataMap1);
                  },
                ),
                const Text(':نمودار وظایف', style: boldText),
                MyPieChart(dataMap: controller.dataMap2),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

额外优化点

  • 避免double.parse(taskFinish.length.toString())这种冗余写法,直接用taskFinish.length.toDouble()更简洁;
  • 可以给MyPieChart添加空数据判断,防止传入空Map时出错;
  • 异步操作建议添加异常捕获,避免加载失败时崩溃:
    Future<void> reportFunction() async {
      try {
        var taskBox = await Hive.openBox('task');
        // ... 原有逻辑
      } catch (e) {
        print('加载数据失败: $e');
        // 可以设置默认数据
        dataMap1.value = {'خطا': 1};
      }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 01:50:33