Flutter - Create Image Container with Round Corners and Splash Effect

Introduction

In this article I'm going to explain you about how image with round corners and splash effect is created using Flutter widgets. Before doing some coding, let's see how images are loaded in Flutter and what the splash effect means.

Images in flutter

In flutter apps, we can load images from network, assets (App resources) or from the file system. Loading images from network is very easy task in flutter using Image.network constructor.

Image.network(
    'https://raw.githubusercontent.com/flutter/website/master/src/_includes/code/layout/lakes/images/lake.jpg',
    )
    

If you want to load images from network and cache it for offline usage, you can use CachedNetworkImage widget. You need to add cached_network_image dependency to use it. Click here to see installation instructions.

CachedNetworkImage(
    placeholder: CircularProgressIndicator(),
    imageUrl: 'https://github.com/flutter/website/blob/master/src/_includes/code/layout/lakes/images/lake.jpg?raw=true',
);
        

Assets are the app resources which are bundled with the app to use during runtime. To use images from assets, first you have to add images to the app folder and declare image path under assets in pubspec.yaml file.

flutter:
assets:
    - assets/my_icon.png
    - assets/background.png

Then these assets can be loaded using AssetImage ImageProvider or using Image.asset constructor.

  • Using Image.asset
    Image.asset('images/cat.png')
  • Using AssetImage
    AssetImage('graphics/background.png')

Splash effect

The ripple effect we get when clicked on some UI element is referred to as Splash effect. In flutter we can use InkWell to add splash effect to our widgets. We can use Ink widget to get image with splash (but not the round corners) as given in the below code.

Container(
    width: 160.0,
    height: 160.0,
    alignment: Alignment.center,
    child: Ink.image(
        fit: BoxFit.cover,
        alignment: Alignment.center,
        image: AssetImage('images/default_avatar.jpg'),
        child: InkWell(
        child: Container(
            width: 160.0,
            height: 160.0,
        ),
        borderRadius: BorderRadius.all(Radius.circular(0.0)),
        onTap: () {},
        ),
    ),
);
    

Coding

The challenge we face here is, it's not possible to add round corners to the image. So, if you want to add rounded corners to the image, the more creative way is to use ClipRRect widget. The InkWell widget actually draws ink reactions on the Material widget that we provided as it's ancestor. So if we don't wrap it with Material widget, splash will become invisible when image is added to the layout. Because image is an opaque object. We're going to use Stack widget to draw both InkWell and image container. Here we're drawing InkWell widget on top of image container.

Stack(
    alignment: Alignment.center,
    children: [
        Container(
        width: 160.0,
        height: 160.0,
        child: ClipRRect(
                borderRadius: BorderRadius.all(Radius.circular(16.0)),
                child: Image.asset('images/default_avatar.jpg'),
            ),
        ),
        Material(
        type: MaterialType.transparency,
        child: InkWell(
                borderRadius: BorderRadius.all(Radius.circular(16.0)),
                child: Container(
                    width: 160.0,
                    height: 160.0,
                    ),
                onTap: () {},
            ),
        ),
    ],
);
    

Normal look

Splash effect

Finishing up

To give premium look for our widget, let's give it a drop shadow and a border.

Stack(
    alignment: Alignment.center,
    children: [
        Container(
        decoration: BoxDecoration(
            border: Border.all(color: AppColors.primaryColor, width: 2.0),
            borderRadius: BorderRadius.all(Radius.circular(16.0)),
            boxShadow: [
            BoxShadow(
                    offset: Offset(0.0, 4.0),
                    spreadRadius: -8.0,
                    color: Colors.black,
                    blurRadius: 12.0,
                ),
            ],
        ),
        width: 160.0,
        height: 160.0,
        child: ClipRRect(
                borderRadius: BorderRadius.all(Radius.circular(16.0)),
                child: Image.asset('images/default_avatar.jpg'),
            ),
        ),
        Material(
        type: MaterialType.transparency,
        child: InkWell(
                borderRadius: BorderRadius.all(Radius.circular(16.0)),
                child: Container(
                    width: 160.0,
                    height: 160.0,
                    ),
                onTap: () {},
            ),
        ),
    ],
);

Final look

Preview

Comments

  1. Nice post... Make more. It's really needed for beginners. For the beginners I recommend this post too... https://androidride.com/flutter-background-image/

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete

Post a Comment

Popular posts from this blog

AVR Analog Comparator

JAudioTagger - ID3 tagger library