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

Flutter中Image.asset加载完成后如何获取实际渲染尺寸?

Flutter 图片加载完成后获取容器实际尺寸方案

问题原因

你之前的实现获取到0值的核心原因:

  • initState中绑定的addPostFrameCallback触发时仅完成了页面首次绘制,此时图片还未完成解码加载,父容器未被图片撑开,尺寸为初始的0
  • frameBuilder触发时仅代表图片帧解码完成,此时父容器还未完成重绘更新尺寸,直接调用_getSizes拿到的还是重绘前的旧值

可用解决方案

方案1:修改frameBuilder回调逻辑(改动最小)

在frameBuilder检测到图片帧加载完成后,再调度一次后帧回调,等父容器完成重绘后再获取尺寸,仅需要修改frameBuilder内的逻辑:

frameBuilder: (BuildContext context, Widget child, int? frame, bool wasSynchronouslyLoaded) {
  if (wasSynchronouslyLoaded) {
    print('wasSynchronouslyLoaded');
  }
  if (frame != null) {
    // 等待本次重绘完成后再获取尺寸
    WidgetsBinding.instance!.addPostFrameCallback((_) {
      _getSizes();
    });
  }
  return child;
}

方案2:监听ImageStream加载状态(更稳定)

ImageProvider本身提供了加载状态监听能力,你可以通过ImageStreamListener监听图片加载完成事件,再配合后帧回调拿尺寸,该方案对网络图片、本地图片通用,不受frameBuilder逻辑影响:
完整修改后的代码示例:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

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

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

class _MyAppState extends State<MyApp> {
  final GlobalKey _imgKey = GlobalKey();
  // 提前定义图片资源
  final AssetImage _assetImg = const AssetImage('assets/images/landscape_big.jpg');

  _getSizes() {
    final RenderBox renderBox = _imgKey.currentContext!.findRenderObject() as RenderBox;
    final boxSize = renderBox.size;
    print("width: ${boxSize.width}, height: ${boxSize.height}");
  }

  @override
  void initState() {
    super.initState();
    // 监听图片加载完成事件
    _assetImg.resolve(ImageConfiguration.empty).addListener(
      ImageStreamListener((ImageInfo info, bool synchronousLoad) {
        // 图片加载完成后等待重绘完成再拿尺寸
        WidgetsBinding.instance!.addPostFrameCallback((_) {
          _getSizes();
        });
      })
    );
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Test Image Load',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Image Asset Load'),
        ),
        body: Center(
          child: Container(
            key: _imgKey,
            child: Image(image: _assetImg)
          )
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            _getSizes();
          },
          child: const Icon(Icons.update),
          backgroundColor: Colors.green,
        ),
      )
    );
  }
}

常见问题说明

官方Image.asset没有提供直接的onLoad回调参数,但可以通过上述ImageStreamListener监听图片加载状态,不需要额外引入第三方控制器。


内容的提问来源于stack exchange,提问作者mr.incredible

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 19:18:01