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

Flutter中API获取行星数据显示时RangeError错误的解决方案求助

解决Flutter中PlanetInfo数组访问的RangeError问题

错误原因分析

  1. StatelessWidget无法触发initState:当前组件是StatelessWidget,但重写了仅属于StatefulWidget的initState方法,导致getPlanetData从未执行,PlanetInfo始终为空数组。
  2. 异步数据未做状态管理:即使调用了网络请求,异步操作完成前组件已完成build,此时访问空数组的索引必然触发越界错误。
  3. 索引使用错误:卫星数量被存在PlanetInfo[0],但代码中错误使用PlanetInfo[1]来显示该数据,进一步加剧索引越界问题。

修复步骤

1. 转为StatefulWidget

只有StatefulWidget支持状态更新和initState生命周期方法,能正确处理异步数据加载后的UI刷新。

2. 管理异步加载状态

添加加载状态标记,在数据未返回时显示加载提示,避免直接访问空数组。

3. 修正索引对应关系

确保卫星数量、重力、密度分别对应数组的0、1、2索引。

4. 增加异常处理

处理API请求失败或字段缺失的情况,避免崩溃。

修复后的完整代码

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:xperience/Models/planets.dart';

class PlanetDescNoMGD extends StatefulWidget {
  final Planet planeteee;

  const PlanetDescNoMGD({Key? key, required this.planeteee}) : super(key: key);

  @override
  State<PlanetDescNoMGD> createState() => _PlanetDescNoMGDState();
}

class _PlanetDescNoMGDState extends State<PlanetDescNoMGD> {
  List<dynamic> planetInfo = [];
  bool isLoading = true;

  Future<void> getPlanetData() async {
    try {
      var url = "https://api.le-systeme-solaire.net/rest/bodies/${widget.planeteee.planetApi}";
      final uri = Uri.parse(url);
      final response = await http.get(uri);
      final jsondata = jsonDecode(response.body);

      setState(() {
        // 处理可能为空的字段,给默认值
        planetInfo.add(jsondata["moons"]?.length ?? 0);
        planetInfo.add(jsondata["gravity"] ?? "N/A");
        planetInfo.add(jsondata["density"] ?? "N/A");
        isLoading = false;
      });
    } catch (e) {
      setState(() {
        isLoading = false;
        // 请求失败时设置默认数据
        planetInfo = [0, "N/A", "N/A"];
      });
    }
  }

  @override
  void initState() {
    super.initState();
    getPlanetData();
  }

  @override
  Widget build(BuildContext context) {
    if (isLoading) {
      return const Center(child: CircularProgressIndicator(color: Colors.white));
    }

    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceAround,
      children: <Widget>[
        Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            const Text(
              "No. of moons",
              style: TextStyle(color: Colors.white, fontWeight: FontWeight.w700),
            ),
            const SizedBox(height: 12),
            Text("${planetInfo[0]}", style: const TextStyle(color: Colors.white))
          ],
        ),
        Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            const Text(
              "Gravity",
              style: TextStyle(color: Colors.white, fontWeight: FontWeight.w600),
            ),
            const SizedBox(height: 12),
            Text("${planetInfo[1]} m/s²", style: const TextStyle(color: Colors.white))
          ],
        ),
        Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            const Text(
              "Density",
              style: TextStyle(color: Colors.white, fontWeight: FontWeight.w600),
            ),
            const SizedBox(height: 12),
            Text("${planetInfo[2]} g/cm³", style: const TextStyle(color: Colors.white))
          ],
        ),
      ],
    );
  }
}

关键修复点说明

  • 转为StatefulWidget后,initState正常执行,setState能在数据加载完成后刷新UI。
  • isLoading状态避免了数据未就绪时访问空数组的问题,同时提供友好的加载提示。
  • 修正索引对应关系,确保数据展示正确。
  • 增加异常捕获和字段空值处理,提升组件的稳定性。

内容的提问来源于stack exchange,提问作者Shreyas K S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 16:20:23