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

Flutter报错type 'Null' is not a subtype of type 'RenderBox'如何解决?

错误原因
  • 调用时机错误:在_SmallState构造函数中直接执行坐标获取逻辑时,组件尚未执行build流程,所有绑定了GlobalKey的GridView子元素还未挂载到渲染树,key.currentContext返回null,强制转换为RenderBox类型就会触发空类型转换异常。即使将调用逻辑移到initState中也会出现相同问题,因为initState执行阶段组件仍未完成渲染挂载。
  • 列表赋值逻辑错误:初始化positions为空列表后直接通过下标positions[i]赋值,会触发数组下标越界异常,空列表不存在对应索引的存储位置。
  • 类型转换缺少校验:直接使用as RenderBox强制转换没有做前置空校验和类型校验,即使渲染完成,也存在返回非RenderBox类型渲染对象的可能,会触发转换异常。
修复步骤
  1. 移除State构造函数中的initOffsetsPositions调用,改为监听首帧渲染完成回调后再执行坐标获取逻辑,Flutter提供的addPostFrameCallback回调会在组件第一帧渲染完成、所有元素已挂载到渲染树后触发。
  2. 修改positions列表的赋值逻辑,改用add方法追加元素,避免下标越界。
  3. 给RenderBox的获取逻辑增加空校验和类型校验,避免强制转换异常。
修复后代码
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

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

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

class _SmallState extends State<Small> {
  late Keys keys;
  late List<Offset> positions;

  _SmallState() {
    keys = Keys();
    positions = [];
  }

  List<String> images = [
    'https://static.javatpoint.com/tutorial/flutter/images/flutter-logo.png',
    'https://simg.nicepng.com/png/small/107-1076994_white-square-outline-plain-black-background-square.png',
    'https://static.javatpoint.com/tutorial/flutter/images/flutter-logo.png',
    'https://static.javatpoint.com/tutorial/flutter/images/flutter-logo.png',
    'https://static.javatpoint.com/tutorial/flutter/images/flutter-logo.png',
    'https://static.javatpoint.com/tutorial/flutter/images/flutter-logo.png',
    'https://static.javatpoint.com/tutorial/flutter/images/flutter-logo.png',
    'https://static.javatpoint.com/tutorial/flutter/images/flutter-logo.png',
    'https://static.javatpoint.com/tutorial/flutter/images/flutter-logo.png'
  ];

  void initOffsetsPositions() {
    List<GlobalKey> keyList = keys.getListOfKeys();
    print(keyList);
    positions.clear();
    for (int i = 0; i < keyList.length; i++) {
      final offset = getOffsetsPositions(keyList[i]);
      if (offset != null) {
        positions.add(offset);
        print(positions[i]);
      }
    }
  }

  Offset? getOffsetsPositions(GlobalKey key) {
    final renderObject = key.currentContext?.findRenderObject();
    if (renderObject is RenderBox) {
      Offset position = renderObject.globalToLocal(Offset.zero);
      Size size = renderObject.size;
      print('Size: ${size.width}, ${size.height}');
      return position;
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      initOffsetsPositions();
    });
    return Center(
      child: Container(
        padding: const EdgeInsets.all(12.0),
        child: GridView.builder(
          itemCount: images.length,
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 3, crossAxisSpacing: 4.0, mainAxisSpacing: 4.0),
          itemBuilder: (BuildContext context, int index) {
            return Stack(
              children: [
                Positioned(
                  child: Container(
                    key: keys.getKeyOfList(index),
                    child: Image.network(images[index]),
                  ),
                ),
              ],
            );
          },
        ),
      ),
    );
  }
}

class Keys {
  static final key0 = GlobalKey();
  static final key1 = GlobalKey();
  static final key2 = GlobalKey();
  static final key3 = GlobalKey();
  static final key4 = GlobalKey();
  static final key5 = GlobalKey();
  static final key6 = GlobalKey();
  static final key7 = GlobalKey();
  static final key8 = GlobalKey();
  final List<GlobalKey> keyList = [
    key0,
    key1,
    key2,
    key3,
    key4,
    key5,
    key6,
    key7,
    key8,
  ];
  GlobalKey getKeyOfList(index) {
    return keyList[index];
  }

  List<GlobalKey> getListOfKeys() {
    return keyList;
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 15:06:00