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

Flutter使用GridView.builder时出现RangeError索引越界报错如何解决

Flutter GridView.builder索引越界问题修复

问题现象

使用GridView.builder渲染自定义卡片列表时,触发RangeError索引越界报错,报错提示索引值超出0..1的有效范围。

现有GridView代码

Container(
              height: 400,
              child: GridView.builder(
                  gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                      crossAxisCount: 2),
                  itemBuilder: (context, index) {
                    return gridCard(card: card[index]);
                  }))

列表定义代码

import 'package:flutter/material.dart';
import 'package:interstellar/Elements/gridCards.dart';

List<GridItem> card = [
  GridItem(
      spaceImg:
          ('https://images.pexels.com/photos/37347/office-sitting-room-executive-sitting.jpg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'),
      spaceName: 'Hive Net Work Hub',
      spacePrice: '25/hr',
      spaceAdd: 'E Lopez St. Brgy San Vicente Jaro'),
  GridItem(
      spaceImg:
          ('https://images.pexels.com/photos/2635038/pexels-photo-2635038.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2'),
      spaceName: 'Thinking Box Study Hub',
      spacePrice: '25/hr',
      spaceAdd: 'Timawa Street, Molo, Iloilo City, Philippines'),
];

class GridItem {
  final String spaceImg;
  final String spaceName;
  final String spacePrice;
  final String spaceAdd;

  const GridItem(
      {required this.spaceImg,
      required this.spaceName,
      required this.spacePrice,
      required this.spaceAdd});
}

自定义卡片组件代码

import 'package:flutter/material.dart';
import 'package:interstellar/Elements/gridItem.dart';

Widget gridCard({required GridItem card}) => Container(
        child: Column(children: [
      Expanded(
          child: AspectRatio(
              aspectRatio: 16 / 9, child: Image.network(card.spaceImg))),
      SizedBox(
        height: 10,
      ),
      Row(
        children: [Text(card.spaceName)],
      ),
      Row(
        children: [Text(card.spacePrice)],
      ),
      Row(
        children: [Text(card.spaceAdd)],
      )
    ]));

报错信息

════════ Exception caught by widgets library ═══════════════════════════════════
The following RangeError was thrown building:
RangeError (index): Invalid value: Not in inclusive range 0..1: 2

════════ Exception caught by widgets library ═══════════════════════════════════
RangeError (index): Invalid value: Not in inclusive range 0..1: 3
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════
RangeError (index): Invalid value: Not in inclusive range 0..1: 4
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════
RangeError (index): Invalid value: Not in inclusive range 0..1: 5
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════
RangeError (index): Invalid value: Not in inclusive range 0..1: 6
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════
RangeError (index): Invalid value: Not in inclusive range 0..1: 7
════════════════════════════════════════════════════════════════════════════════

报错根因

索引越界的核心原因是GridView.builder未设置itemCount参数。GridView.builder默认采用懒加载机制,会持续生成子项填满可滚动区域,而你的card列表仅包含2条数据(有效索引范围0~1),当组件尝试构建索引≥2的子项时,访问card[index]就会触发RangeError。
另外自定义卡片组件中Expanded包裹AspectRatio的写法存在布局约束冲突,即使解决索引问题也可能出现渲染异常。

修复方案

1. 补充GridView.builder必填参数

给GridView.builder添加itemCount参数告知组件列表总长度,同时补充网格间距、子项宽高比配置优化显示效果:

Container(
  height: 400,
  child: GridView.builder(
    // 新增:指定列表总长度,解决索引越界
    itemCount: card.length,
    gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
      crossAxisCount: 2,
      crossAxisSpacing: 10, // 横向子项间距
      mainAxisSpacing: 10, // 纵向子项间距
      childAspectRatio: 0.7, // 子项宽高比,可根据实际样式调整
    ),
    itemBuilder: (context, index) {
      return gridCard(card: card[index]);
    },
  ),
)

2. 修复卡片组件布局问题

调整卡片内部嵌套逻辑,移除不合理的Expanded包裹,补充布局样式避免内容溢出:

Widget gridCard({required GridItem card}) => Container(
  padding: const EdgeInsets.all(8),
  decoration: BoxDecoration(
    border: Border.all(color: Colors.grey.shade300),
    borderRadius: BorderRadius.circular(8),
  ),
  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      AspectRatio(
        aspectRatio: 16 / 9,
        child: Image.network(
          card.spaceImg,
          fit: BoxFit.cover, // 图片按比例填充,避免拉伸
        ),
      ),
      const SizedBox(height: 10),
      Text(
        card.spaceName,
        style: const TextStyle(fontWeight: FontWeight.bold),
        maxLines: 1,
        overflow: TextOverflow.ellipsis, // 长文本截断
      ),
      const SizedBox(height: 4),
      Text(
        card.spacePrice,
        style: TextStyle(color: Colors.green.shade700),
      ),
      const SizedBox(height: 4),
      Text(
        card.spaceAdd,
        style: const TextStyle(fontSize: 12, color: Colors.grey),
        maxLines: 2,
        overflow: TextOverflow.ellipsis,
      ),
    ],
  ),
);

补充注意事项

  • GridView.builder适用于长列表/大量数据渲染场景,必须传入itemCount明确列表总长度,否则组件会无限构建子项。
  • 如果列表数据量较少,也可以直接使用GridView.count构造函数,不需要手动写builder逻辑,用法更简单。
  • 自定义组件时要避免Expanded和AspectRatio的不合理嵌套,两者都会干预子组件的约束,嵌套不当很容易触发布局异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 02:31:13