Create rounded cached image in Flutter

DartFlutter

Dart Problem Overview


I want to create a circle image where the image is fetched from the network and is also cached in Flutter.

Here is a code I found for a round image fetched from the network but the image not being cached.

new Container(
    width:80.0,
    height: 80.0,
    decoration: new BoxDecoration(
    shape: BoxShape.circle,
        image: new DecorationImage(
            image: new NetworkImage('https://pbs.twimg.com/profile_images/945853318273761280/0U40alJG_400x400.jpg'),
        ),
    ),
),

Now I found a widget for fetching, caching and presenting a image from the network

new CachedNetworkImage(imageUrl: 'https://pbs.twimg.com/profile_images/945853318273761280/0U40alJG_400x400.jpg')

But when I replace the NetworkImage widget with this CachedNetworkImage, it gives me an error saying the NetworkImage is not type image.

How can I achieve a round image that can be cached?

Edited: I tried this as suggested in the answer, but still got the same error: The argument type 'CachedNetworkImage' can't be assigned to the parameter type 'DecorationImage'.

              decoration: new BoxDecoration(
                shape: BoxShape.circle,
                image: new CachedNetworkImage(image: 
                      'https://pbs.twimg.com/profile_images/945853318273761280/0U40alJG_400x400.jpg'),
              ),

Dart Solutions


Solution 1 - Dart

The CachedNetworkImage has a builder (ImageWidgetBuilder) to further customize the display of the image. Try it this way:

CachedNetworkImage(
  imageUrl: 'https://pbs.twimg.com/profile_images/945853318273761280/0U40alJG_400x400.jpg',
  imageBuilder: (context, imageProvider) => Container(
    width: 80.0,
    height: 80.0,
    decoration: BoxDecoration(
      shape: BoxShape.circle,
      image: DecorationImage(
        image: imageProvider, fit: BoxFit.cover),
    ),
  ),
  placeholder: (context, url) => CircularProgressIndicator(),
  errorWidget: (context, url, error) => Icon(Icons.error),
),

placeholder and errorWidget are widgets, which means you can put any widget in there and customize them as you wish.

Solution 2 - Dart

DecorationImage takes an ImageProvider and not a widget.

There are two ways to solve this problem:

The cached_image_network provides a class that extends ImageProvider, i.e. CachedNetworkImageProvider:

Container(
  width: 80.0,
  height: 80.0,
  decoration: BoxDecoration(
    shape: BoxShape.circle,
    image: DecorationImage(
      image: CachedNetworkImageProvider('https://pbs.twimg.com/profile_images/945853318273761280/0U40alJG_400x400.jpg'),
    ),
  ),
)

You could also just omit the DecorationImage widget because the BoxDecoration will work on any widget:

Container(
  width: 80.0,
  height: 80.0,
  decoration: BoxDecoration(
    shape: BoxShape.circle,
  ),
  child: CachedNetworkImage('https://pbs.twimg.com/profile_images/945853318273761280/0U40alJG_400x400.jpg'),
)

In the latter example, I am using the regular CachedNetworkImage, which will return a widget.

Solution 3 - Dart

ClipOval widget is used to clip child widget into round shapes.

ClipOval(
  child: CachedNetworkImage(imageUrl: "https://pbs.twimg.com/profile_images/945853318273761280/0U40alJG_400x400.jpg",
   width: 80.0,
   height: 80.0,
  ),
)

Solution 4 - Dart

The combination of CircleAvatar and CachedNetworkImageProvider solves your problem. Here is an example:

CircleAvatar(
  backgroundImage: CachedNetworkImageProvider(
  'https://pbs.twimg.com/profile_images/945853318273761280/0U40alJG_400x400.jpg',
  ),
),

Solution 5 - Dart

in my case this save my time , mybe you too.

CachedNetworkImage(
  imageUrl: url,
  errorWidget: (context, url, error) => Text("error"),
  imageBuilder: (context, imageProvider) => CircleAvatar(
    radius: 50,
    backgroundImage: imageProvider,
   ),
  );

Solution 6 - Dart

It will work by using a Container and ClipRRect. Here is an example:

Container(
  width: 160,
  height: 160,
    child: ClipRRect(
      borderRadius: BorderRadius.circular(80),
      child: CachedNetworkImage(
        fit: BoxFit.cover,
        imageUrl: '[YOUR URL]',
        errorWidget: (
          context,
          url,
          error,
        ) =>
          const Icon(Icons.error),
        progressIndicatorBuilder: (
          context,
          url,
          downloadProgress,
        ) =>
          Center(
            child: CircularProgressIndicator(
              value: downloadProgress.progress),
            ),
          )
      ),
    ),

The width and height of your Container widget are important and both should be the same.

I hope that will be useful for others ;-)

Solution 7 - Dart

A general solution for pictures with any dimension and corner radius:

Container(
   width: 100,
   height: 125,
   decoration: BoxDecoration(
      borderRadius: BorderRadius.circular(34.0),
      color: Colors.grey,
   ),
   child: ClipRRect(
      borderRadius: BorderRadius.circular(34.0),
      child: CachedNetworkImage(
         imageUrl: "url",
         fit: BoxFit.cover,
         placeholder: (context, url) => Center(
            child: SizedBox(
               width: 40.0,
               height: 40.0,
               child: new CircularProgressIndicator(),
            ),
         ),
         errorWidget: (context, url, error) => new Icon(Icons.error),
      ),
   ),
),

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondshukertjrView Question on Stackoverflow
Solution 1 - DartKakiangView Answer on Stackoverflow
Solution 2 - DartcreativecreatorormaybenotView Answer on Stackoverflow
Solution 3 - DartdshukertjrView Answer on Stackoverflow
Solution 4 - Dartheisenberg91View Answer on Stackoverflow
Solution 5 - Dartmalik kurosakiView Answer on Stackoverflow
Solution 6 - DartrphonikaView Answer on Stackoverflow
Solution 7 - DartPaulView Answer on Stackoverflow