Back to Posts

Creating Rounded Edges for Images in Flutter

7 min read
<div style="text-align: center;"> <img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzAwIiBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDMwMCAyMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPCEtLSBSb3VuZGVkIEltYWdlIGV4YW1wbGUgLS0+CiAgPHJlY3Qgd2lkdGg9IjMwMCIgaGVpZ2h0PSIyMDAiIGZpbGw9IiNGRkYiIHN0cm9rZT0iIzAwMCIvPgogIDx0ZXh0IHg9IjE1MCIgeT0iMTAwIiBmb250LWZhbWlseT0iQXJpYWwiIGZvbnQtc2l6ZT0iMTIiIGZpbGw9IiMyMTIxMjEiIHRleHQtYW5jaG9yPSJtaWRkbGUiPlJvdW5kZWQgSW1hZ2U8L3RleHQ+Cjwvc3ZnPg==" alt="Rounded Image Example" width="300" /> </div>

Rounded edges can add a polished and modern look to your Flutter application's images. This guide will show you various techniques to create rounded edges for images in Flutter.

Basic Techniques

1. Using ClipRRect

class RoundedImageWithClipRRect extends StatelessWidget {
  const RoundedImageWithClipRRect({super.key});

  @override
  Widget build(BuildContext context) {
    return ClipRRect(
      borderRadius: BorderRadius.circular(20),
      child: Image.network(
        'https://example.com/image.jpg',
        width: 200,
        height: 200,
        fit: BoxFit.cover,
      ),
    );
  }
}

2. Using Container with BorderRadius

class RoundedImageWithContainer extends StatelessWidget {
  const RoundedImageWithContainer({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 200,
      height: 200,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(20),
        image: const DecorationImage(
          image: NetworkImage('https://example.com/image.jpg'),
          fit: BoxFit.cover,
        ),
      ),
    );
  }
}

Advanced Techniques

1. Custom Border Radius

class CustomBorderRadiusImage extends StatelessWidget {
  const CustomBorderRadiusImage({super.key});

  @override
  Widget build(BuildContext context) {
    return ClipRRect(
      borderRadius: const BorderRadius.only(
        topLeft: Radius.circular(30),
        bottomRight: Radius.circular(30),
      ),
      child: Image.network(
        'https://example.com/image.jpg',
        width: 200,
        height: 200,
        fit: BoxFit.cover,
      ),
    );
  }
}

2. Rounded Image with Border

class RoundedImageWithBorder extends StatelessWidget {
  const RoundedImageWithBorder({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 200,
      height: 200,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(20),
        border: Border.all(
          color: Colors.blue,
          width: 2,
        ),
        image: const DecorationImage(
          image: NetworkImage('https://example.com/image.jpg'),
          fit: BoxFit.cover,
        ),
      ),
    );
  }
}

3. Rounded Image with Shadow

class RoundedImageWithShadow extends StatelessWidget {
  const RoundedImageWithShadow({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 200,
      height: 200,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(20),
        boxShadow: [
          BoxShadow(
            color: Colors.black.withOpacity(0.3),
            blurRadius: 10,
            offset: const Offset(0, 5),
          ),
        ],
        image: const DecorationImage(
          image: NetworkImage('https://example.com/image.jpg'),
          fit: BoxFit.cover,
        ),
      ),
    );
  }
}

Special Cases

1. Circular Image

class CircularImage extends StatelessWidget {
  const CircularImage({super.key});

  @override
  Widget build(BuildContext context) {
    return ClipOval(
      child: Image.network(
        'https://example.com/image.jpg',
        width: 200,
        height: 200,
        fit: BoxFit.cover,
      ),
    );
  }
}

2. Rounded Image with Gradient Overlay

class RoundedImageWithGradient extends StatelessWidget {
  const RoundedImageWithGradient({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 200,
      height: 200,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(20),
        gradient: LinearGradient(
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
          colors: [
            Colors.transparent,
            Colors.black.withOpacity(0.7),
          ],
        ),
        image: const DecorationImage(
          image: NetworkImage('https://example.com/image.jpg'),
          fit: BoxFit.cover,
        ),
      ),
    );
  }
}

Best Practices

  1. Performance

    • Use appropriate image sizes
    • Implement proper caching
    • Consider using placeholder
    • Optimize image loading
  2. Responsiveness

    • Use relative sizes
    • Consider different screen sizes
    • Implement proper scaling
    • Test on various devices
  3. Accessibility

    • Add proper alt text
    • Consider color contrast
    • Implement proper focus
    • Test with screen readers
  4. User Experience

    • Use consistent styling
    • Consider loading states
    • Implement error handling
    • Provide fallback images

Common Issues and Solutions

  1. Image Loading

    // Use placeholder while loading
    Image.network(
      'https://example.com/image.jpg',
      loadingBuilder: (context, child, loadingProgress) {
        if (loadingProgress == null) return child;
        return CircularProgressIndicator(
          value: loadingProgress.expectedTotalBytes != null
              ? loadingProgress.cumulativeBytesLoaded /
                  loadingProgress.expectedTotalBytes!
              : null,
        );
      },
    )
  2. Error Handling

    // Handle image loading errors
    Image.network(
      'https://example.com/image.jpg',
      errorBuilder: (context, error, stackTrace) {
        return const Icon(Icons.error);
      },
    )
  3. Memory Management

    // Use proper image caching
    CachedNetworkImage(
      imageUrl: 'https://example.com/image.jpg',
      placeholder: (context, url) => CircularProgressIndicator(),
      errorWidget: (context, url, error) => Icon(Icons.error),
    )

Conclusion

Creating rounded edges for images in Flutter is a powerful way to enhance your app's visual appeal. Remember to:

  • Choose the right technique for your needs
  • Consider performance implications
  • Implement proper error handling
  • Follow best practices

Happy coding!