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
相关产品推荐
相关产品推荐

