Flutter网络图片加载插件url_image的使用
Flutter网络图片加载插件url_image的使用
UrlImage
是一个跨平台的小部件,用于从网络通过URL加载远程图像并支持持久缓存。该小部件支持Flutter支持的所有光栅图像格式,以及SVG图像。
如果您需要从网络显示SVG图片或需要持久缓存以快速在应用重启后显示远程图像,那么 UrlImage
可能是一个不错的选择。
功能特性
- 通过URL从网络显示图像,包括光栅和矢量格式。
- 将图像存储在持久缓存中,因此当应用程序重新启动时,所有之前下载的图像将立即从文件存储中显示出来。
- 即使最后一个小部件被释放,图像提供者也不会从内存缓存中移除,因此当小部件再次出现在屏幕上时,图像会立即显示。
- 平滑地更新内部存储。如果远程存储中先前下载的图像发生了变化,小部件将显示更改动画。
- 自定义占位符构建器,即加载小部件构建器和错误小部件构建器。
- 自定义文件存储、下载器和矢量解码器。
- 支持使用标准的 logging 包进行消息日志记录,并且可以自定义日志级别。
- 可选的通知,例如成功或失败尝试加载图像,或者以原始尺寸显示图像(这在图像用作照片查看器画廊时可能很有用)。
- 可以像普通小部件一样绘制图像,也可以作为墨水绘制在底层材料上,因此图像上会出现褶皱。
开始使用
首先,在项目中添加 url_image
包并导入它:
flutter pub add url_image
import 'package:url_image/url_image.dart';
然后配置 config
,提供自定义委托:
UrlImage.config
..fileStorage = MyFileStorage()
..downloader = const MyDownloader()
..vectorDecoder = const MyVectorDecoder()
;
您需要首先使用项目中首选的工具实现这些委托。例如,您可以使用 http
或 dio
来实现 DownloadDelegate
,或者您可能已经实现了自己的HTTP客户端,或者您可以编写提供自定义头和需要授权请求的特殊图像仓库。
如果不提供任何委托,当试图使用委托时,小部件将在日志中显示相应的消息。
FileStorageDelegate
此委托为 UrlImageCache
提供功能,使其能够从文件存储中存储和加载图像。它是可选的。如果不提供此委托,当应用程序重新启动时,小部件不会从文件存储中恢复数据,因此所有图像将以某些延迟出现(需要一些时间才能从互联网下载图像)。
DownloadDelegate
此委托负责使用其URL下载图像。您可以按您希望的方式实现下载方法,但最终您必须向小部件提供下载图像的字节和格式(光栅/矢量)。这也是可选的,但几乎不会在不从网络下载图像的情况下使用 UrlImage
。
VectorDecodeDelegate
您可能需要从网络显示SVG图片。借助此委托,UrlImage
可以显示SVG图片。这很简单,只需导入 flutter_svg
包并在实现的委托中使用它来解码SVG图片,如下所示:
[@override](/user/override)
Future<VectorInfo> decode(final Uint8List bytes, {
bool clipViewbox = true,
}) async
{
final info = await vg.loadPicture(SvgBytesLoader(bytes), null,
clipViewbox: clipViewbox,
);
return VectorInfo(info.picture, info.size);
}
就这样!现在您可以使用 UrlImage
小部件下载并显示SVG图片,只需指定SVG图片的URL即可,就像对其他位图图像一样。
您可以在该包的 example
项目中看到实现示例。
日志记录
如果您使用 logging
包,可以为小部件提供日志级别,如下所示:
Logger.root.level = Level.ALL;
Logger.root.onRecord.listen(onMessage);
UrlImage.config.logLevel = Level.OFF;
使用方式
然后您只需像通常使用 Image
或 Image.network
小部件一样在您的小部件树中使用 UrlImage
:
UrlImage(
name: 'user_profile',
url: user.pictureUrl,
fit: BoxFit.contain,
),
示例代码
以下是完整的示例代码,展示了如何使用 UrlImage
插件。
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:logging/logger.dart';
import 'package:url_image/url_image.dart';
import 'downloader.dart';
import 'file_storage.dart';
import 'vector_decoder.dart';
Future<void> main() async {
Logger.root.level = Level.ALL;
Logger.root.onRecord.listen(onMessage);
UrlImage.config
..fileStorage = MyFileStorage()
..downloader = const MyDownloader()
..vectorDecoder = const MyVectorDecoder();
await Future.delayed(const Duration(seconds: 2));
runApp(const MyApp());
}
void onMessage(final LogRecord record) {
var msg = '${record.level.name[0]} ${record.time} ${record.message}';
if (record.error != null) {
msg += ' (${record.error})';
}
log(msg,
time: record.time,
sequenceNumber: record.sequenceNumber,
level: record.level.value,
name: record.loggerName,
zone: record.zone,
error: record.error,
stackTrace: record.stackTrace,
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
const MyHomePage({super.key, required this.title});
[@override](/user/override)
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
static const urls = [
'https://raw.githubusercontent.com/darkstarx/url_image/main/example/media/nature1.jpg',
'https://raw.githubusercontent.com/darkstarx/url_image/main/example/media/nature2.jpg',
'https://raw.githubusercontent.com/darkstarx/url_image/main/example/media/nature1.svg',
'https://raw.githubusercontent.com/darkstarx/url_image/main/example/media/nature2.svg',
];
[@override](/user/override)
Widget build(final BuildContext context) {
final url = urls[_index];
final name = Uri.parse(url).pathSegments.last;
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: InkWell(
onTap: () {},
child: Column(
children: [
Expanded(
child: Center(
child: UrlImage(name: name, url: url),
),
),
const SizedBox(height: kToolbarHeight),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => setState(() {
if (++_index >= urls.length) _index = 0;
}),
child: const Icon(Icons.navigate_next),
),
);
}
var _index = 0;
}
更多关于Flutter网络图片加载插件url_image的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter网络图片加载插件url_image的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用url_image
插件来加载网络图片的示例代码。不过需要注意的是,截至我最后更新的时间(2023年),url_image
并不是一个广为人知的官方或广泛使用的Flutter插件。更常见的选择是使用Flutter社区广泛采用的cached_network_image
插件。但为了符合你的要求,我会假设url_image
插件的使用方式类似于其他图像加载插件,并给出一个假设性的示例。
首先,确保你的pubspec.yaml
文件中已经添加了url_image
插件的依赖(注意:如果url_image
实际上不存在,你需要替换为如cached_network_image
这样的实际插件)。
dependencies:
flutter:
sdk: flutter
url_image: ^x.y.z # 假设的版本号,实际使用时请替换为最新版本
然后运行flutter pub get
来安装依赖。
接下来,在你的Dart代码中,你可以这样使用url_image
(假设性的用法,实际使用时请参考插件的官方文档):
import 'package:flutter/material.dart';
import 'package:url_image/url_image.dart'; // 假设的导入路径
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('URL Image Example'),
),
body: Center(
child: UrlImage.network(
'https://example.com/path/to/your/image.jpg', // 替换为你的图片URL
placeholder: (context, url) => CircularProgressIndicator(), // 加载中的占位符
errorWidget: (context, url, error) => Icon(Icons.error), // 加载失败的错误图标
),
),
),
);
}
}
在这个示例中,UrlImage.network
方法用于从指定的URL加载网络图片。我们提供了两个可选参数:
placeholder
:一个函数,返回一个Widget,用于在图片加载时显示。在这个例子中,我们使用了CircularProgressIndicator
作为占位符。errorWidget
:一个函数,返回一个Widget,用于在图片加载失败时显示。在这个例子中,我们使用了Icon(Icons.error)
作为错误图标。
请注意,由于url_image
可能并不是一个真实存在的插件,上述代码是基于假设的用法。如果你发现url_image
不存在或文档不足,建议使用cached_network_image
插件,它提供了类似的功能,并且社区支持广泛。以下是使用cached_network_image
的示例:
dependencies:
flutter:
sdk: flutter
cached_network_image: ^3.1.0 # 使用最新版本
然后在你的Dart代码中:
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Cached Network Image Example'),
),
body: Center(
child: CachedNetworkImage(
imageUrl: 'https://example.com/path/to/your/image.jpg', // 替换为你的图片URL
placeholder: (context, url) => CircularProgressIndicator(), // 加载中的占位符
errorWidget: (context, url, error) => Icon(Icons.error), // 加载失败的错误图标
),
),
),
);
}
}
这个示例与前面的假设性url_image
用法非常相似,但CachedNetworkImage
是一个真实存在且广泛使用的插件。