Flutter网络图片不适合圆形头像

134

我正在尝试从一个API中检索大量图像。我希望这些图像以圆形的形式显示,因此我使用了CircleAvatar小部件,但我始终得到方形格式的图像。 以下是图像的屏幕截图:

enter image description here

这是我正在使用的代码:

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

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


你尝试过使用 fit: BoxFit.cover 吗? - chemamolins
1
只需使用CircleAvatar的backgroundImage属性即可。6个Flutter CircleAvatar示例教程 - Athira Reddy
25个回答

270

这样会有效:您需要使用backgroundImage:属性来将其适配到圆形中。

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,
              )

4
存储中的图像,可以使用Image.file(Image.file(File file))来获取。CircleAvatar能够处理吗? - M.ArslanKhan
2
@M.ArslanKhan 是的。您可以在backgroundImage属性中使用AssetImage。 - alperen.emeksiz
3
有时候你会像我一样想要将它与FadeInImage一起使用...这种情况下最好的方法是将其包装在ClipOval小部件中...以下是代码片段: backgroundColor: Colors.grey, child: ClipOval( child: FadeInImage.assetNetwork( placeholder: placeholderPath, image: imageUrl, ), ), );``` - Alex Rindone

107

AppBar 操作小部件列表中遇到了类似的问题。

这对我有用:

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

52

如果你不想使用 CircleAvatar,以下是你可以使用的方法。

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

2
为什么有人不愿尝试圆形头像? - Asbah Riyas
1
@AsbahRiyas 因为图像无法填充可用空间。尝试在非常小的圆形头像中使用大图像,然后您就会知道问题出在哪里了。 - Adam Smaka
1
我不使用CircleAvatar的原因是它会动画显示背景颜色,而我并不想要这个效果。换句话说,这个解决方案非常适合我,谢谢。 - Jelle Blaauw
很好,运行正常。 - johnson

22

如果有人想要创建带边框的圆形图片,请尝试以下方法。

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

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

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


实际上这是最完美的实现。适用于所有图像尺寸,不会扭曲图像。谢谢。 - RealRK
除非必要,否则不要使用剪辑(Clips),在这种情况下它并不是必需的。与直接更改边框半径相比,剪辑可能更加昂贵:https://flutter.dev/docs/perf/rendering/best-practices - satvikpendem

13
你需要使用NetworkImageAssetImageFileImageMemoryImage或类似的内容。 由于Flutter架构其图像类的方式,您不能直接使用Image.networkImage.asset或类似的内容。
一个例子:
CircleAvatar(
  radius: 100.0,
  backgroundImage: NetworkImage(...),
)

CircleAvatar 中的 backgroundImage 属性需要传入一个 ImageProvider 类型的参数。然而,Image.network 和其他类并没有直接继承 ImageProvider,它们仅仅继承了 StatefulWidget,尽管它们内部使用了 NetworkImage。这就是为什么在其他答案中看到使用 ClipOvalClipRRect 的原因。这些类接受一个 Widget 类型的参数,所以它们不像 CircleAvatar 和一些类那样具有特定的要求。

因此,在使用 CircleAvatar 时,你应该使用 NetworkImage 和类似的类,而对于只需要传入一个 Widget 类型的参数的小部件,你可以使用 Image.network 和类似的类。

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


12

只需backgroundImage 放在 CircleAvatar 中即可。

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

这对于网络图片对我来说不起作用,有什么想法为什么吗? - Leland Reardon

6

如果有人试图将圆形图像放入应用栏操作中,请尝试以下解决方案,它应该有效。

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

              ),
            ),
          )

AspectRatio 首先尝试使用布局约束(这里是 appbar)允许的最大宽度。如果我去除填充,图像半径将为 appbar 的大小。因此,添加填充来控制圆形图像的大小。


6
 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,
                ),
        ),
      ),

6

这对我很有帮助。

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

5

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接