How to Round image corners with BoxFit.contain in flutter

Viewed 6152

My problem is when I wrap the image with a container that has a specific size and uses BoxFit.contain property for it will not round the image. checkout the below image: image link
I think the image cant round itself because it cants expand to fill container. I know that I can use BoxFit.cover but I want to use BoxFit.contain because I have limited space and images that can be of any sizes. my code:

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

    );
  }
4 Answers

You have to wrap your ClipRRect widget with Center or any Align widget.

Most of the widgets will try to fill its parent, if the parent doesn't specify any alignment property.

In your case the ClipRRect filled its parent Container (300x300) since the container doesn't specify any alignment to its child. And Image with contain property will try to maintain image ratio and being centered in ClipRRect widget. So It made ClipRRect corners invisible or no effect.

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

Edit: Here I used Center widget. But you can also just simply specify alignment property in the Container widget.

Try using BoxFit.fill if i understood correctly this is what you want to achieve :

@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,
            ),
          ),
        ),
      ),
    );
  }

Put in a codepen demo

EDIT for a workaround to your question :

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

      final url = 'https://i.stack.imgur.com/lkd0a.png';
      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...');
            }
          },
        ),
      ),
    );
  }
}

use stack for it

Stack(
  children: <Widget>[
  ],
)

Here, I’m simply using a container with an image inside it

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