我正在使用缓存的网络图像从 firebase 加载图像,如果图像的 URL 为空,则会加载一个带有图标的圆形头像。
它在模拟器中工作正常,但总是发布错误 当图片 url 为空时:
I/flutter ( 6907): CacheManager: Failed to download file from with error:
I/flutter ( 6907): Invalid argument(s): No host specified in URI
当图片url不为空时:
I/flutter ( 6907): CacheManager: Failed to download file from with error:
I/flutter ( 6907): Invalid argument(s): No host specified in URI
══╡ EXCEPTION CAUGHT BY IMAGE RESOURCE SERVICE ╞════════════════════════════════════════════════════
The following ArgumentError was thrown resolving an image codec:
Invalid argument(s): No host specified in URI
When the exception was thrown, this was the stack:
#0 _HttpClient._openUrl (dart:_http/http_impl.dart:2662:9)
#1 _HttpClient.openUrl (dart:_http/http_impl.dart:2568:7)
#2 IOClient.send (package:http/src/io_client.dart:35:38)
#3 HttpFileService.get (package:flutter_cache_manager/src/web/file_service.dart:35:44)
#4 WebHelper._download (package:flutter_cache_manager/src/web/web_helper.dart:117:24)
#5 WebHelper._updateFile (package:flutter_cache_manager/src/web/web_helper.dart:99:28)
<asynchronous suspension>
#6 WebHelper._downloadOrAddToQueue (package:flutter_cache_manager/src/web/web_helper.dart:67:7)
<asynchronous suspension>
Image provider: CachedNetworkImageProvider("", scale: 1.0)
Image key: CachedNetworkImageProvider("", scale: 1.0):
CachedNetworkImageProvider("", scale: 1.0)
════════════════════════════════════════════════════════════════════════════════════════════════════
我该如何解决这个显示错误?
这是代码:
class ProfilePicture extends GetView<UserController> {
const ProfilePicture({
Key? key,
this.enabled = false,
}) : super(key: key);
final bool enabled;
double get radius => enabled ? 40.0 : 30.0;
@override
Widget build(BuildContext context) {
return Obx(
() {
return Hero(
tag: 'profile_hero',
child: GestureDetector(
child: CachedNetworkImage(
imageUrl: controller.user?.photoURL ?? '',
placeholder: (context, url) => Container(),
errorWidget: (context, url, error) {
return Stack(
children: [
CircleAvatar(
radius: radius,
backgroundColor: Get.theme.brightness == Brightness.dark
? Colors.transparent
: Get.theme.scaffoldBackgroundColor,
child: Icon(Icons.person_outline_rounded,
size: radius * 1.5,
color: Get.theme.brightness == Brightness.dark
? Colors.white
: primaryColor),
),
Obx(
() => Visibility(
visible: controller.loading.value,
child: SizedBox(
height: radius * 2,
width: radius * 2,
child: const CircularProgressIndicator(),
),
),
),
],
);
},
imageBuilder: (_, imageProvider) {
return Stack(
children: [
CircleAvatar(
radius: radius,
backgroundImage: imageProvider,
),
Obx(() {
return Visibility(
visible: controller.loading.value,
child: SizedBox(
height: radius * 2,
width: radius * 2,
child: const CircularProgressIndicator(
strokeWidth: 5,
),
),
);
}),
],
);
},
),
onTap: () {
if (enabled) {
showModalBottomSheet(
context: context,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0),
),
builder: (_) => const ImagePickerBottomModal(),
);
} else {
Get.to(
const ProfileScreen(),
routeName: AppRoutes.routeProfile,
curve: Curves.fastOutSlowIn,
transition: Transition.downToUp,
);
}
},
),
);
},
);
}
}
如果您没有要加载的图像,则根本不应该创建
CachedNetworkImage
。
一种方法:
@override
Widget build(BuildContext context) {
var photoURL = controller.user?.photoURL;
var fallback = Stack(
children: [
CircleAvatar(...)
],
);
return Obx(
() {
return Hero(
tag: 'profile_hero',
child: GestureDetector(
child: (photoURL == null)
? fallback
: CachedNetworkImage(
imageUrl: photoURL,
placeholder: (context, url) => Container(),
errorWidget: (context, url, error) => fallback,
...
一个 hacky 的替代方案是只提供一个不可路由的 URL,这肯定会失败(例如
https://0.0.0.0/
)。
也许你可以做这样的事情。根据您的网址创建两个
CacheNetworkImage
。一个代表 null,另一个代表 not null。
child: (controller.user?.photoURL == null) ?
CacheNetworkImage ( // with CircleAvatar ) : CacheNetworkImage(// with image path)
它是 cached_network_image 的开放问题。您必须检查 URL 是否已验证,如下所示。
检查 URL 是否有效的功能。
static bool validateURL(String? input) {
if (stringHasValue(input)) {
return Uri.parse(input!).host.isNotEmpty;
} else {
return false;
}
}