如何在Flutter中使用BoxFit.contain对图像进行圆角处理

8
我的问题是,当我将图片包装在一个具有特定大小并使用BoxFit.contain属性的容器中时,它无法圆角化。请查看下面的图片:image link
我认为图片无法自己变成圆角是因为它不能扩展来填充容器。我知道可以使用BoxFit.cover,但我想使用BoxFit.contain,因为我有限的空间并且图片可以是任何大小。我的代码:
@override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey,
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Container(
          color: Colors.red,
          height: 300,
          width: 300,
          child: ClipRRect(
            borderRadius: BorderRadius.circular(16),
            child: Image.network(
              'https://i.ytimg.com/vi/fq4N0hgOWzU/maxresdefault.jpg',
              fit: BoxFit.contain,
            ),
          ),
        ),
      ),

    );
  }

我没有完全理解你的问题。我知道你想使用Boxfit.container,但是你到底有什么困扰呢?容器的背景、图像大小还是其他什么? - Prefect
@Iammuratc 我想要裁剪我的图片,而不是容器。容器只是为了显示我有限的空间。我将ClipRrect添加为Image.network的父级,但图片没有发生任何变化。 - Payam Zahedi
4个回答

11

您需要将 ClipRRect widget 包裹在 Center 或任何一个 Align widget 中。

大多数widget会尝试填充其父级,如果父级没有指定任何对齐属性。

在您的情况下,ClipRRect 填充了其父级 Container (300x300),因为容器没有指定其子级的对齐方式。带有 contain 属性的图像会尝试保持图像比例并在 ClipRRect widget 中居中。因此,它使得 ClipRRect 的角落不可见或没有效果。

演示: Dartpad

Scaffold(
  backgroundColor: Colors.grey,
  appBar: AppBar(
    title: Text("My image size"),
  ),
  body: Center(
    child: Container(
      color: Colors.red,
      height: 300,
      width: 300,
      child: Center(
        child: ClipRRect(
          borderRadius: BorderRadius.circular(16),
          child: Image.network(
            'https://mfiles.alphacoders.com/847/847991.jpg',
            fit: BoxFit.contain,
          ),
        ),
      ),
    ),
  ),
)

编辑: 这里我使用了Center小部件。但您还可以在Container小部件中指定对齐属性。


谢谢你的回答,这正是我想要的,而且这将正确地工作。你能解释一下为什么我们应该使用align或center widget吗? - Payam Zahedi

0

0

如果我理解正确,您想要实现的是使用 BoxFit.fill

@override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.grey,
      appBar: AppBar(
        title: Text("My image size"),
      ),
      body: Center(
        child: Container(
          color: Colors.red,
          height: 300,
          width: 300,
          child: ClipRRect(
            borderRadius: BorderRadius.circular(16),
            child: Image.network(
              'https://i.ytimg.com/vi/fq4N0hgOWzU/maxresdefault.jpg',
              fit: BoxFit.fill,
            ),
          ),
        ),
      ),
    );
  }

在CodePen演示中放入代码

编辑:针对您的问题的解决方法:

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    Future<Widget> getImage() async {
      final Completer<Widget> completer = Completer();

      final url = 'https://istack.dev59.com/lkd0a.webp';
      final image = NetworkImage(url);
      final config = await image.obtainKey(const ImageConfiguration());
      final load = image.load(config);

      final listener = new ImageStreamListener((ImageInfo info, isSync) async {
        print(info.image.width);
        print(info.image.height);

        completer.complete(Container(
            child: Image(
          image: image,
          height: info.image.height.toDouble(),
          width: info.image.width.toDouble(),
        )));
      });

      load.addListener(listener);
      return completer.future;
    }

    return Scaffold(
      backgroundColor: Colors.grey,
      appBar: AppBar(
        title: Text("My image size"),
      ),
      body: Center(
        child: FutureBuilder<Widget>(
          future: getImage(),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return snapshot.data;
            } else {
              return Text('LOADING...');
            }
          },
        ),
      ),
    );
  }
}

BoxFit.fill 对于像 image 这样的垂直方向的正方形图片不会呈现出很好的效果。 - Crazy Lazy Cat
然后你使用 BoxFit.cover。你不能两全其美,既想忽略宽高比以填充你的框,又想保持宽高比,使图像看起来仍然很好。或者你可以尝试通过使用 ImageStreamListener 并根据从 ImageInfo 获取的图像大小调整你的框来绕过这个问题。如果这是你想要的,请查看我的编辑。 - Firas BENMBAREK

0

使用堆栈来实现它

Stack(
  children: <Widget>[
  ],
)

这里,我只是使用一个包含图像的容器

 Container(
      decoration: Box Decoration(
        image: Decoration Image(
          image: Asset Image('images/new_york.jpg'),
          fit: Box Fit . fit Height,
        ),
      ),
    ),

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