import 'dart:io'; import 'package:flutter/material.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter_svg/flutter_svg.dart'; import '../core/app_export.dart'; extension ImageTypeExtension on String { ImageType get imageType { if (this.startsWith('http') || this.startsWith('https')) { return ImageType.network; } else if (this.endsWith('.svg')) { return ImageType.svg; } else if (this.startsWith('file: //')) { return ImageType.file; } else { return ImageType.png; } } } enum ImageType { svg, png, network, file, unknown } // ignore_for_file: must_be_immutable class CustomImageWidget extends StatelessWidget { CustomImageWidget({ this.imageUrl, this.height, this.width, this.color, this.fit, this.alignment, this.onTap, this.radius, this.margin, this.border, this.placeHolder = 'assets/images/no-image.jpg', this.errorWidget, this.semanticLabel, }); ///[imageUrl] is required parameter for showing image final String? imageUrl; final double? height; final double? width; final BoxFit? fit; final String placeHolder; final Color? color; final Alignment? alignment; final VoidCallback? onTap; final BorderRadius? radius; final EdgeInsetsGeometry? margin; final BoxBorder? border; /// Optional widget to show when the image fails to load. /// If null, a default asset image is shown. final Widget? errorWidget; /// Semantic label for the image to improve accessibility final String? semanticLabel; @override Widget build(BuildContext context) { return alignment != null ? Align(alignment: alignment!, child: _buildWidget()) : _buildWidget(); } Widget _buildWidget() { return Padding( padding: margin ?? EdgeInsets.zero, child: InkWell( onTap: onTap, child: _buildCircleImage(), ), ); } ///build the image with border radius _buildCircleImage() { if (radius != null) { return ClipRRect( borderRadius: radius ?? BorderRadius.zero, child: _buildImageWithBorder(), ); } else { return _buildImageWithBorder(); } } ///build the image with border and border radius style _buildImageWithBorder() { if (border != null) { return Container( decoration: BoxDecoration( border: border, borderRadius: radius, ), child: _buildImageView(), ); } else { return _buildImageView(); } } Widget _buildImageView() { if (imageUrl != null) { switch (imageUrl!.imageType) { case ImageType.svg: return Container( height: height, width: width, child: SvgPicture.asset( imageUrl!, height: height, width: width, fit: fit ?? BoxFit.contain, colorFilter: this.color != null ? ColorFilter.mode( this.color ?? Colors.transparent, BlendMode.srcIn) : null, semanticsLabel: semanticLabel, ), ); case ImageType.file: return Image.file( File(imageUrl!), height: height, width: width, fit: fit ?? BoxFit.cover, color: color, semanticLabel: semanticLabel, ); case ImageType.network: return CachedNetworkImage( height: height, width: width, fit: fit, imageUrl: imageUrl!, color: color, placeholder: (context, url) => Container( height: 30, width: 30, child: LinearProgressIndicator( color: Colors.grey.shade200, backgroundColor: Colors.grey.shade100, ), ), errorWidget: (context, url, error) => errorWidget ?? Image.asset( placeHolder, height: height, width: width, fit: fit ?? BoxFit.cover, semanticLabel: semanticLabel, ), ); case ImageType.png: default: return Image.asset( imageUrl!, height: height, width: width, fit: fit ?? BoxFit.cover, color: color, semanticLabel: semanticLabel, ); } } return SizedBox(); } }