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

修改Flutter相册示例为列表时遇RangeError,求解决方案

问题解决:Flutter列表赋值导致RangeError错误

错误原因

你代码里的RangeError是因为初始化了空列表futureAlbum = []后,直接通过futureAlbum[index] = fetchAlbum()的方式赋值——空列表没有对应索引的位置,所以触发索引越界错误。

修正方案

方案1:使用add方法添加元素

修改initState中的循环逻辑,用add代替索引赋值:

@override
void initState() {
  super.initState();
  for (int index = 0; index < 5; index++) {
    futureAlbum.add(fetchAlbum());
  }
}

方案2:初始化列表时指定长度

如果需要提前确定列表长度,可以在初始化时指定长度,再通过索引赋值:

List<Future<EngagementText>> futureAlbum = List.filled(5, Future.value(EngagementText()));

@override
void initState() {
  super.initState();
  for (int index = 0; index < 5; index++) {
    futureAlbum[index] = fetchAlbum();
  }
}

额外优化:批量处理多个Future请求

如果需要等待所有请求完成后再展示数据,推荐用Future.wait批量处理:

late Future<List<EngagementText>> futureEngagementTexts;

@override
void initState() {
  super.initState();
  // 批量发起5个请求,等待全部完成
  futureEngagementTexts = Future.wait(List.generate(5, (_) => fetchAlbum()));
}

对应的FutureBuilder也需要调整为处理列表数据:

FutureBuilder<List<EngagementText>>(
  future: futureEngagementTexts,
  builder: (context, snapshot) {
    if (snapshot.hasData) {
      // 展示第4个元素(索引3)的text
      return Text(snapshot.data![3].text ?? '无内容');
    } else if (snapshot.hasError) {
      return Text('${snapshot.error}');
    }
    return const CircularProgressIndicator();
  },
)

完整修正后的代码

import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

Future<EngagementText> fetchAlbum() async {
  final response = await http.get(Uri.parse(
      'https://ListeningToGod.org/SermonEngagement/TextFiles/2024-09-0801a.json'));

  if (response.statusCode == 200) {
    return EngagementText.fromJson(
        jsonDecode(response.body) as Map<String, dynamic>);
  } else {
    throw Exception('Failed to load album');
  }
}

class EngagementText {
  String? version;
  String? date;
  String? text;
  List<Links>? links;

  EngagementText({this.version, this.date, this.text, this.links});

  EngagementText.fromJson(Map<String, dynamic> json) {
    try {
      version = json['version'];
      date = json['date'];
      text = json['text'];
      if (json['links'] != null) {
        links = <Links>[];
        json['links'].forEach((v) {
          links!.add(Links.fromJson(v));
        });
      }
    } catch (e) {
      date = "2024-01-01";
      text = "Dummy Text";
    }
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['version'] = version;
    data['date'] = date;
    data['text'] = text;
    if (links != null) {
      data['links'] = links!.map((v) => v.toJson()).toList();
    }
    return data;
  }
}

class Links {
  String? link;
  String? text;

  Links({this.link, this.text});

  Links.fromJson(Map<String, dynamic> json) {
    link = json['link'];
    text = json['text'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['link'] = link;
    data['text'] = text;
    return data;
  }
}

void main() => runApp(const MyApp());

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List<Future<EngagementText>> futureAlbum = [];

  @override
  void initState() {
    super.initState();
    // 用add方法添加元素,避免索引越界
    for (int index = 0; index < 5; index++) {
      futureAlbum.add(fetchAlbum());
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Fetch Data Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Fetch Data Example'),
        ),
        body: Center(
          child: FutureBuilder<EngagementText>(
            future: futureAlbum[3],
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return Text(snapshot.data!.text ?? '无内容');
              } else if (snapshot.hasError) {
                return Text('${snapshot.error}');
              }
              return const CircularProgressIndicator();
            },
          ),
        ),
      ),
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 23:43:17