缓存网络图像 - URI 中未指定主机

问题描述 投票:0回答:3

我正在使用缓存的网络图像从 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,
                );
              }
            },
          ),
        );
      },
    );
  }
}
flutter flutter-layout
3个回答
6
投票

如果您没有要加载的图像,则根本不应该创建

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/
)。


1
投票

也许你可以做这样的事情。根据您的网址创建两个

CacheNetworkImage
。一个代表 null,另一个代表 not null。

child: (controller.user?.photoURL == null) ?
 CacheNetworkImage ( // with CircleAvatar ) : CacheNetworkImage(// with image path)

0
投票

它是 cached_network_image开放问题。您必须检查 URL 是否已验证,如下所示。

检查 URL 是否有效的功能。

         static bool validateURL(String? input) {
            if (stringHasValue(input)) {
              return Uri.parse(input!).host.isNotEmpty;
            } else {
              return false;
            }
          }
© www.soinside.com 2019 - 2024. All rights reserved.