【问题标题】:Flutter Network Image does not fit in Circular AvatarFlutter 网络图像不适合圆形头像
【发布时间】:2019-04-30 00:10:33
【问题描述】:

我正在尝试从 api 检索一堆图像。我希望图像以圆形形式显示,所以我使用CircleAvatar Widget,但我一直以方形格式获取图像。 这是图片的截图

这是我正在使用的代码

ListTile(leading: CircleAvatar(child: Image.network("${snapshot.data.hitsList[index].previewUrl}",fit: BoxFit.scaleDown,)),),

我尝试使用BoxFit 的所有属性,例如cover、contain、fitWidth、fitHeight 等,但它们都不起作用。

【问题讨论】:

标签: image dart flutter flutter-layout


【解决方案1】:

以下在我的情况下有效:

child: new CircleAvatar(
        backgroundColor: Colors.white,
        child: ClipRect(
          child: Image.network(
            'url-to-image',
            fit: BoxFit.cover,
          ),
        ),
      )

【讨论】:

    【解决方案2】:

    你可以这样做

    创建一个用户Avtar类

    class Avatar extends StatelessWidget {
      Avatar(
        this.user,
      );
      final UserModel user;
    
      @override
      Widget build(BuildContext context) {
        if ((user?.photoUrl == '') || (user?.photoUrl == null)) {
          return LogoGraphicHeader();
        }
        return Hero(
          tag: 'User Avatar Image',
          child: CircleAvatar(
              foregroundColor: Colors.blue,
              backgroundColor: Colors.white,
              radius: 70.0,
              child: ClipOval(
                child: Image.network(
                  user?.photoUrl,
                  fit: BoxFit.cover,
                  width: 120.0,
                  height: 120.0,
                ),
              )),
        );
      }
    }
    

    并像这样使用它

    Avatar(controller.firestoreUser.value),
    

    【讨论】:

      【解决方案3】:

      使用 AvatarView 库 https://pub.dev/packages/avatar_view,它提供了以圆形/矩形形式显示网络/资产图像的功能。

      要使用添加下面的依赖项

      dependencies:
        avatar_view: ^1.0.0+3
      

      示例:

              AvatarView(
                        radius: 60,
                        borderColor: Colors.yellow,
                        avatarType: AvatarType.CIRCLE,
                        backgroundColor: Colors.red,
                        imagePath:
                        "https://images.pexels.com/photos/415829/pexels-photo-415829.jpeg?cs=srgb&dl=pexels-pixabay-415829.jpg",
                        placeHolder: Container(
                          child: Icon(Icons.person, size: 50,),
                        ),
                        errorWidget: Container(
                          child: Icon(Icons.error, size: 50,),
                        ),
                      ),
      

      它还提供了在小部件周围添加边框的功能,更多示例请访问上面的链接

      输出:

      【讨论】:

        【解决方案4】:

        将您的 CircleAvatar 小部件包装在 Stack 小部件下。

         return Stack(
              children: [
                CircleAvatar(
                  radius: 50.0,
                  backgroundImage: NetworkImage(
                      'https://i.pinimg.com/474x/0c/eb/c3/0cebc3e2a01fe5abcff9f68e9d2a06e4.jpg'),
                ),
              ],
            );
        

        【讨论】:

        • 这应该被接受的答案
        【解决方案5】:

        这对我有用

        Transform.scale(
                scale: 0.6,
                child: ClipOval(
                  child: Image.network(
                    <IMAGE URL HERE>,
                  ),
                ),
              )
        

        【讨论】:

          【解决方案6】:
          Column(
                          crossAxisAlignment: CrossAxisAlignment.center,
                          mainAxisAlignment: MainAxisAlignment.spaceAround,
                          children: [
                            GestureDetector(
                              onTap: () {
                                Navigator.push(
                                  context,
                                  MaterialPageRoute(builder: (context) => MyApp7()),
                                );
                              },
                              child: CircleAvatar(
                                radius: 50,
                                // backgroundColor: Colors.amber,
                                child: CircleAvatar(
                                    backgroundColor: Colors.grey[50],
                                    radius: 50,
                                    // child: Image.asset("assets/images/nophotoMale.png")
                                    backgroundImage:
                                        AssetImage("assets/images/nophotoMale.png")),
                              ),
                            ),
                          ],
                        ),
          

          【讨论】:

          • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
          • 是的,我会添加
          【解决方案7】:

          只需在CircleAvatar 内使用 backgroundImage

           CircleAvatar(
                backgroundImage: AssetImage("assets/images/dia.jpg",),
              ),
          

          【讨论】:

            【解决方案8】:

            如果有人试图在应用栏操作中放置圆形图像。尝试以下解决方案,它应该可以工作。

                     Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: AspectRatio(
                          aspectRatio: 1,
                          child: CircleAvatar(
                            backgroundImage: NetworkImage('https://picsum.photos/seed/picsum/200/500'),
            
                          ),
                        ),
                      )
            

            AspectRatio 首先尝试布局约束(此处为应用栏)允许的最大宽度。如果我删除填充图像半径将是 appbar 大小。所以添加padding来控制圆形图片的大小。

            【讨论】:

              【解决方案9】:

              在此解决方案中,您可以通过容器调整图像大小并通过剪辑椭圆来剪辑图像,然后通过卡片为图像添加阴影。

              Container(
                width: 100,
                height: 100,
                child: InkWell(
                  onTap: () {},
                  child: Card(
                    elevation: 5,
                    shape: RoundedRectangleBorder(
                      side: BorderSide(color: Colors.grey),
                      borderRadius: const BorderRadius.all(
                        Radius.circular(45.0),
                      ),
                    ),
                    child: Container(
                      child: ClipOval(
                          child: CachedNetworkImage(
                        imageUrl: '{image-url}',
                        imageBuilder: (context, imageProvider) => Container(
                          decoration: BoxDecoration(
                            image: DecorationImage(
                              image: imageProvider,
                              fit: BoxFit.fill,
                            ),
                          ),
                        ),
                        placeholder: (context, url) => Container(
                          height: 5,
                          width: 5,
                          child: CircularProgressIndicator(
                            valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
                          ),
                        ),
                        errorWidget: (context, url, error) => Icon(Icons.error),
                      )),
                    ),
                  ),
                ));
              

              【讨论】:

                【解决方案10】:
                                    CachedNetworkImage(
                                        placeholder: (context, url) => Center(
                                              child: CircularProgressIndicator(),
                                            ),
                                        errorWidget: (context, url, error) =>
                                            new Icon(Icons.error),
                                        imageBuilder: (context, imageProvider) => Container(
                                            width: 60.0,
                                            height: 60.0,
                                            decoration: BoxDecoration(
                                                shape: BoxShape.circle,
                                                image: DecorationImage(
                                                    image: imageProvider,
                                                    fit: BoxFit.contain))),
                                        fit: BoxFit.contain,
                                        imageUrl:
                                            "${Constants.MEDIA_LINK}${state.review.company.logo}"),
                

                【讨论】:

                  【解决方案11】:

                  尝试了几次才弄清楚这一点。所有这些答案都没有帮助我。最后,我插入到圆形头像中的图片被拉伸到容器的边界,该容器在其上方 2 个实例处。也许有些人,在经历了这里的答案之后,仍然有我遇到的问题。我用FittedBox解决了约束问题

                               GestureDetector(
                                      onTap: () => getImage(),
                                      child: Container(
                                        width: MediaQuery.of(context).size.width,
                                        decoration: BoxDecoration(
                                          color: Colors.orange,
                                        ),
                                        //padding: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
                                        child: Container(
                                            width: 140,
                                            height: 160,
                                            child: FittedBox(
                                              child: picture(),
                                            )),
                                      ),
                                    ),
                  

                  这是我使用的图片()的代码。我觉得picture()里面的容器已经不用了,自己试试吧:)

                  Widget picture() {
                  if (_image == null) {
                    return CircleAvatar(
                        radius: 70,
                        child: Icon(
                          Icons.person,
                          size: 150,
                          color: Colors.grey[900],
                        ));
                  } else {
                    return Container(
                      width: 140,
                      height: 140,
                      child: CircleAvatar(
                        radius: 70,
                        backgroundImage: FileImage(_image),
                      ),
                    );
                  }
                  

                  【讨论】:

                    【解决方案12】:
                     CircleAvatar(
                            radius: 26,
                            backgroundColor: Colors.white,
                            child: ClipOval(
                              child: _bytesImage == null
                                  ? new Text('No image value.')
                                  : Image.memory(
                                      _bytesImage,
                                      width: 60,
                                      height: 60,
                                      fit: BoxFit.cover,
                                    ),
                            ),
                          ),
                    

                    【讨论】:

                      【解决方案13】:

                      您需要使用NetworkImage、AssetImage、FileImage、MemoryImage 或类似名称。由于 Flutter 构建图像类的方式,您不能直接使用 Image.network、Image.asset 或类似名称。

                      一个例子:

                      CircleAvatar(
                        radius: 100.0,
                        backgroundImage: NetworkImage(...),
                      )
                      

                      CircleAvatar 中的backgroundImage 期望接收ImageProvider 作为参数。但是,Image.network 等并没有直接扩展ImageProvider 类,它们只是扩展了StatefulWidget 类,尽管它们在内部使用了NetworkImage。这就是为什么您在其他答案中看到正在使用 ClipOval 或 ClipRRect 的原因。这些类接受Widget,因此它们不像CircleAvatar 和类似的类那样特别。

                      因此,对于CircleAvatar,您应该使用NetworkImage 和类似的类而不是这些解决方法,对于只需要Widget 的小部件,您可以使用Image.network 和类似的。

                      不使用剪辑的另一个原因是它们可能比直接更改边框半径更昂贵:https://flutter.dev/docs/perf/rendering/best-practices

                      【讨论】:

                        【解决方案14】:

                        我遇到了同样的问题。在圆形头像中使用 clipoval 会使它变成椭圆形。 但这解决了这个问题。

                        CircleAvatar(
                        
                                     radius:25.0,
                        
                                     backgroundImage: NetworkImage(
                                                '${image_url}',
                        
                        
                                                ),
                                                backgroundColor: Colors.blue,
                                                    ),   
                        
                        

                        【讨论】:

                          【解决方案15】:

                          如果有人打算创建带边框的圆形图像,试试这个。

                          使用ClipOval 小部件并不是完美的解决方案,因为如果图像不是方形的,结果将是椭圆的。

                          CircleAvatar(radius: (52),
                                      backgroundColor: Colors.white,
                                      child: ClipRRect(
                                        borderRadius:BorderRadius.circular(50),
                                        child: Image.asset("assets/pictures/profile.png"),
                                      )
                                  )
                          

                          ClipRRect 小部件防止图像溢出CircleAvatar 小部件。

                          【讨论】:

                          • 其实是最完美的实现。适用于所有图像尺寸,并且不会以任何方式扭曲图像。谢谢
                          【解决方案16】:

                          如果你想显示你的图像覆盖整个圆圈头像,那么你可以这样使用它。如果您的图像没有加载,那么它将显示默认的人形图标。

                           CircleAvatar(
                                        child: ClipOval(
                                                            child: Center(
                                                          child: _image == null
                                                              ? Icon(
                                                                  Icons.person,
                                                                  color: Colors.grey.shade700,
                                                                  size: 100,
                                                                )
                                                              : Image.file(
                                                                  _image,
                                                                  fit: BoxFit.cover,
                                                                  width: MediaQuery.of(context).size.width,
                                                                ),
                                                        ),
                                                      ),
                          
                                                    radius: 50,
                                                    backgroundColor: Colors.grey.shade300,
                                                  ),
                          

                          【讨论】:

                            【解决方案17】:

                            这对我有用

                               CircleAvatar(
                                              child:  ClipRRect(
                                                  borderRadius: new BorderRadius.circular(100.0),
                                                  child:Image.network("https://www.rd.com/wp-content/uploads/2017/09/01-shutterstock_476340928-Irina-Bg-1024x683.jpg"),
                                            ),),
                            

                            【讨论】:

                              【解决方案18】:

                              来到这里是因为我也遇到了 CirclAvatar 和 AppBar 的问题,图像会在高度上拉伸。而不是半径,因为我无法为它提供我正在使用的组件,所以我只是在 appbar 中使用时用一个列包裹了图像。这使得图像不会在高度上拉伸。这样我也可以随时从外部控制尺寸

                              Column(
                                              mainAxisAlignment: MainAxisAlignment.center,
                                              children: <Widget>[
                                                SizedBox(height: 40, width: 40, child: ProfileBadge(),),
                                              ],
                                            )
                              

                              【讨论】:

                                【解决方案19】:

                                我遇到了同样的问题

                                CircleAvatar(
                                             radius: 30.0,
                                             backgroundImage: NetworkImage(imageURL),
                                             backgroundColor: Colors.transparent,
                                             ));
                                

                                解决了我的问题。

                                【讨论】:

                                  【解决方案20】:

                                  使用width/height、fit 的组合并将图像包装在ClipOval 中,如下所示:

                                  CircleAvatar(
                                      child: ClipOval(
                                          child: Image.network(
                                              _photo,
                                              width: 120,
                                              fit: BoxFit.fill
                                          ),
                                      ),
                                      radius: 50,
                                  ),
                                  

                                  【讨论】:

                                    【解决方案21】:
                                      ClipOval(
                                         child: Image.asset(
                                          'assets/dummy.jpg',
                                           fit: BoxFit.contain,
                                           matchTextDirection: true,
                                           height: 50,
                                       ))
                                    

                                    【讨论】:

                                    • 虽然此代码可能/可能无法解决问题,including an explanation 关于如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请编辑您的答案以添加解释。
                                    【解决方案22】:

                                    这是一张带阴影的圆形图片:

                                    child: AspectRatio(
                                        aspectRatio: 1/1,
                                        child: Container(
                                            margin: EdgeInsets.all(
                                                10.0
                                            ),
                                            decoration: BoxDecoration(
                                                borderRadius: BorderRadius.circular(100.0),
                                                boxShadow:[
                                                  BoxShadow(
                                                      color: Color.fromARGB(60, 0, 0, 0),
                                                      blurRadius: 5.0,
                                                      offset: Offset(5.0, 5.0)
                                                  )
                                                ],
                                                image: DecorationImage(
                                                    fit: BoxFit.cover,
                                                    image: NetworkImage(user.image)
                                                )
                                            )
                                        )
                                    )
                                    

                                    【讨论】:

                                      【解决方案23】:

                                      如果您不想使用CircleAvatar,请按照以下方法操作。

                                      ClipOval(
                                        child: Image.network(
                                          'https://via.placeholder.com/150',
                                          width: 100,
                                          height: 100,
                                          fit: BoxFit.cover,
                                        ),
                                      ),
                                      

                                      【讨论】:

                                      • 为什么有人不尝试圈子头像
                                      • @AsbahRiyas 因为图像没有填满可用空间。尝试在非常小的圆形头像中使用大图像,然后您就会知道问题所在。
                                      • 我不使用 CircleAvatar 的一个原因是它会为背景颜色设置动画,这是我不想要的。换句话说,这个解决方案对我来说是完美的,谢谢。
                                      【解决方案24】:

                                      在AppBar 操作小部件列表中存在类似问题。

                                      这对我有用:

                                      CircleAvatar(
                                          radius: 18,
                                          child: ClipOval(
                                              child: Image.network(
                                                'image-url',
                                              ),
                                          ),
                                      ),
                                      

                                      【讨论】:

                                        【解决方案25】:

                                        这将起作用:您需要使用 backgroundImage:property 才能将其放入 Circle。

                                        CircleAvatar(
                                                        radius: 30.0,
                                                        backgroundImage:
                                                            NetworkImage("${snapshot.data.hitsList[index].previewUrl}"),
                                                        backgroundColor: Colors.transparent,
                                                      )
                                        

                                        使用虚拟占位符检查:

                                        CircleAvatar(
                                                        radius: 30.0,
                                                        backgroundImage:
                                                            NetworkImage('https://via.placeholder.com/150'),
                                                        backgroundColor: Colors.transparent,
                                                      )
                                        

                                        【讨论】:

                                        • 还有来自存储的图像,Image.file(Image.file(File file))。 CircleAvatar 能应付吗?
                                        • @M.ArslanKhan 是的。您可以在 backgroundImage 属性中使用 AssetImage。
                                        • 有时您会想像我一样将它与 FadeInImage 一起使用...在这种情况下,最好的方法是将其包装在 ClipOval 小部件中...这是一个 sn-p:@987654324 @
                                        猜你喜欢
                                        • 1970-01-01
                                        • 2022-08-15
                                        • 2023-02-03
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 2020-05-23
                                        • 1970-01-01
                                        • 1970-01-01
                                        • 2020-08-13
                                        相关资源
                                        最近更新 更多