Flutter中从API获取图片存在延迟,如何待图片加载完成后再显示页面?
Flutter实现图片完全加载后再显示页面的方案
方案一:使用FutureBuilder预加载单张图片
将图片加载逻辑封装为Future,通过FutureBuilder监听加载状态,仅当图片加载完成后渲染页面内容,加载过程中显示加载指示器。
class ImageLoadedPage extends StatelessWidget { final String imageUrl = "你的图片API地址"; Future<void> _preloadImage() async { final image = NetworkImage(imageUrl); // 解析图片资源,等待加载完成 await image.resolve(const ImageConfiguration()); } @override Widget build(BuildContext context) { return FutureBuilder( future: _preloadImage(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { // 图片加载完成,渲染目标页面 return Scaffold( body: Center( child: Image.network(imageUrl), ), ); } else if (snapshot.hasError) { // 加载失败时显示错误提示 return const Scaffold( body: Center(child: Text("图片加载失败")), ); } else { // 加载中显示指示器 return const Scaffold( body: Center(child: CircularProgressIndicator()), ); } }, ); } }
方案二:借助cached_network_image预加载并缓存图片
使用第三方库cached_network_image(需先在pubspec.yaml中添加依赖,如cached_network_image: ^3.3.0),利用其预加载能力配合状态管理,完成加载后再显示页面。
import 'package:cached_network_image/cached_network_image.dart'; class PreloadImagePage extends StatefulWidget { final String imageUrl = "你的图片API地址"; @override State<PreloadImagePage> createState() => _PreloadImagePageState(); } class _PreloadImagePageState extends State<PreloadImagePage> { bool _isImageLoaded = false; @override void initState() { super.initState(); _preloadImage(); } Future<void> _preloadImage() async { // 预加载图片到缓存 await CachedNetworkImageProvider(widget.imageUrl).resolve(const ImageConfiguration()); setState(() { _isImageLoaded = true; }); } @override Widget build(BuildContext context) { if (!_isImageLoaded) { return const Scaffold(body: Center(child: CircularProgressIndicator())); } // 图片加载完成,渲染页面 return Scaffold( body: Center( child: CachedNetworkImage(imageUrl: widget.imageUrl), ), ); } }
方案三:手动监听ImageStream实现预加载
无需第三方库,通过监听ImageStream的加载状态,手动控制页面渲染时机,适合对原生API有偏好的场景。
class ManualPreloadPage extends StatefulWidget { final String imageUrl = "你的图片API地址"; @override State<ManualPreloadPage> createState() => _ManualPreloadPageState(); } class _ManualPreloadPageState extends State<ManualPreloadPage> { bool _imageReady = false; @override void initState() { super.initState(); _loadImage(); } Future<void> _loadImage() async { final imageProvider = NetworkImage(widget.imageUrl); final completer = Completer<void>(); final imageStream = imageProvider.resolve(const ImageConfiguration()); ImageStreamListener? listener; listener = ImageStreamListener((info, syncCall) { completer.complete(); imageStream.removeListener(listener!); }); imageStream.addListener(listener); await completer.future; setState(() { _imageReady = true; }); } @override Widget build(BuildContext context) { return _imageReady ? Scaffold(body: Center(child: Image.network(widget.imageUrl))) : const Scaffold(body: Center(child: CircularProgressIndicator())); } }
多图片加载场景处理
如果需要等待多张图片全部加载完成后再显示页面,可使用Future.wait()批量处理预加载任务:
Future<void> _preloadMultipleImages() async { final imageUrls = ["图片地址1", "图片地址2", "图片地址3"]; final preloadFutures = imageUrls.map((url) { return NetworkImage(url).resolve(const ImageConfiguration()); }); await Future.wait(preloadFutures); }
内容的提问来源于stack exchange,提问作者Sibi Kumar
相关产品推荐
相关产品推荐

