美文网首页
Flutter 重复造轮子 (2) Avatar 头像显示组件的

Flutter 重复造轮子 (2) Avatar 头像显示组件的

作者: 半城半离人 | 来源:发表于2023-09-08 10:08 被阅读0次

    详细可以访问仓库 HcUi: 重复创造Flutter 的轮子 在原有组件上拓展 展现出新的特性 (gitee.com)

    介绍

    CircleAvatar组件增强版.头像组件,可以适配文字,图片以及图标。可以设置背景颜色为渐变不局限于圆形 可以增加阴影以及边框
    根据官方圆形头像组件 修改 不局限于圆形可以变化任意形状 实现方式为AnimatedContainer的 foregroundDecoration


    Screenshot_2023-09-07-16-39-51-0900154547.png

    代码演示

    基础用法

                const HcAvatar(
                  radius:10.0,
                  size: 20.0,
                  backgroundImageUrl: 'assets/images/group.png',
                  child: Text("张三"),
                ),
    

    渐变背景

    HcAvatar支持传入Gradient来构建渐变背景

                const HcAvatar(
                  radius:10.0,
                  size: 20.0,
                  gradient: LinearGradient(
                    colors: [Colors.blue, Colors.yellow],
                    stops: [0.1, 0.9],
                    transform: GradientRotation(pi / 2),
                  ),
                  child: Text("张三"),
                ),
    

    展示图标

    child组件一般用来展示文字/icon 如果需要展示图片请用backgroundImageUrl/foregroundImageUrl

                const HcAvatar(
                  radius:20.0,
                  size: 30.0,
                  child: Icon(Icons.icecream_outlined),
                ),
    

    增加阴影

                const HcAvatar(
                  radius: 20.0,
                  size: 40.0,
                  gradient: LinearGradient(
                    colors: [Colors.blue, Colors.yellow],
                    stops: [0.1, 0.9],
                    transform: GradientRotation(pi / 2),
                  ),
                  boxShadow: [
                    BoxShadow(
                      color: Colors.amber,
                      offset: Offset(0, 10),
                      blurRadius: 10,
                    )
                  ],
                  child: Icon(Icons.icecream_outlined),
                ),
    

    增加边框

     HcAvatar(
                        borderColor: Colors.purple,
                        borderWidth: 3,
                        foregroundImageUrl: 'assets/images/icon.jpeg',
                      ),
    

    修改大小

      HcAvatar(
                        size: 20,
                        foregroundImageUrl: 'assets/images/icon.jpeg',
                      ),
    

    特殊用法

    同时设置前景图和背景图 前景图报错展示背景图 背景图报错展示背景颜色

          HcAvatar(
                        foregroundImageUrl: 'assets/images/i1con.jpeg',
                        backgroundImageUrl: 'assets/images/used.png',
                      ),
    

    只展示文字不展示图片

            HcAvatar(
                        child: Text("张三"),
                      ),
    

    背景图片+文字

       HcAvatar(
                        child: Text("张三"),
                        backgroundImageUrl: 'assets/images/icon.jpeg',
                      ),
    

    渐变背景+Icon

          HcAvatar(
                        child: Icon(Icons.icecream_outlined),
                        gradient: HcGradientUtil.generateLinearGradient(
                            colors: [Colors.purple, Colors.black12]),
    
                      ),
    

    API

    props

    参数 说明 类型 默认值 是否必填
    size 组件大小 double 40.0 false
    radius 头像圆角 double 20.0 false
    backgroundColor 图片背景纯色(优先级低于渐变) color - false
    borderColor 边框颜色 color - false
    borderWidth 边框宽度 double - false
    gradient 渐变背景(背景图显示出错时展示) Gradient - false
    foregroundColor 前景色 color - false
    backgroundImageUrl 背景图片地址(前景图片显示出错展示) String - false
    foregroundImageUrl 前景图片地址 String - false
    onForegroundImageError 前景图片显示出错的回调 Function - false
    onBackgroundImageError 背景图片出错的回调 Function - false
    child 背景色上显示的内容 Widget - false
    boxShadow 背景阴影 List<BoxShadow> - false

    显示顺序

    foregroundImageUrl>backgroundImageUrl>gradient>backgroundColor<p>
    foregroundColor的作用是调节child的文字颜色

    Function

    方法名 说明 参数 返回类型
    onForegroundImageError/ onBackgroundImageError 背景图片出错的回调 Function(Object exception, StackTrace? stackTrace) void

    项目源码

    checkAndFixImagePath方法在Flutter 重复造轮子 (1) Image 图片显示组件的封装中有不在此赘述

    ///  头像组件
    class HcAvatar extends StatelessWidget {
      //图片的大小
      final double size;
    
      //图标的圆角
      final double radius;
    
      //背景颜色
      final Color? backgroundColor;
    
      //边框颜色
      final Color? borderColor;
    
      //边框宽度
      final double borderWidth;
    
      //渐变色 渐变色颜色优先度大于Color
      // foregroundImageUrl>backgroundImageUrl>gradient>backgroundColor
      final Gradient? gradient;
    
      //前景色
      final Color? foregroundColor;
    
      //图片背景Url
      final String? backgroundImageUrl;
    
      //图片前景Url
      final String? foregroundImageUrl;
    
      //出错的回调
      final ImageErrorListener? onForegroundImageError;
    
      //出错的回调
      final ImageErrorListener? onBackgroundImageError;
    
      //子组件
      final Widget? child;
    
      //阴影
      final List<BoxShadow>? boxShadow;
    
      const HcAvatar(
          {Key? key,
          this.size = HcSize.defaultAvatarSize,
          this.radius = HcSize.defaultRadius,
          this.backgroundColor,
          this.foregroundColor,
          this.boxShadow,
          this.borderColor,
          this.borderWidth = HcSize.defaultAvatarBorderWidth,
          this.gradient,
          this.child,
          this.backgroundImageUrl,
          this.foregroundImageUrl,
          this.onForegroundImageError,
          this.onBackgroundImageError})
          : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        final ThemeData theme = Theme.of(context);
        final Color? effectiveForegroundColor = foregroundColor ??
            (theme.useMaterial3 ? theme.colorScheme.onPrimaryContainer : null);
        final TextStyle effectiveTextStyle = theme.useMaterial3
            ? theme.textTheme.titleMedium!
            : theme.primaryTextTheme.titleMedium!;
        TextStyle textStyle =
            effectiveTextStyle.copyWith(color: effectiveForegroundColor);
        Color? effectiveBackgroundColor = backgroundColor ??
            (theme.useMaterial3 ? theme.colorScheme.primaryContainer : null);
        if (effectiveBackgroundColor == null) {
          switch (ThemeData.estimateBrightnessForColor(textStyle.color!)) {
            case Brightness.dark:
              effectiveBackgroundColor = theme.primaryColorLight;
              break;
            case Brightness.light:
              effectiveBackgroundColor = theme.primaryColorDark;
              break;
          }
        } else if (effectiveForegroundColor == null) {
          switch (ThemeData.estimateBrightnessForColor(backgroundColor!)) {
            case Brightness.dark:
              textStyle = textStyle.copyWith(color: theme.primaryColorLight);
              break;
            case Brightness.light:
              textStyle = textStyle.copyWith(color: theme.primaryColorDark);
              break;
          }
        }
    
        return AnimatedContainer(
          constraints: BoxConstraints(
            minHeight: size,
            minWidth: size,
            maxWidth: size + borderWidth * 2,
            maxHeight: size + borderWidth * 2,
          ),
          duration: kThemeChangeDuration,
          decoration: BoxDecoration(
            boxShadow: boxShadow,
            border: borderColor != null
                ? Border.all(color: borderColor!, width: borderWidth)
                : null,
            gradient: gradient,
            borderRadius:
                BorderRadius.circular((size + borderWidth * 2) / (size / radius)),
            color: effectiveBackgroundColor,
            image: backgroundImageUrl != null
                ? DecorationImage(
                    image: _buildImageProvider(backgroundImageUrl),
                    onError: onBackgroundImageError,
                    fit: BoxFit.cover,
                  )
                : null,
          ),
          foregroundDecoration: foregroundImageUrl != null
              ? BoxDecoration(
                  image: DecorationImage(
                    image: _buildImageProvider(foregroundImageUrl!),
                    onError: onForegroundImageError,
                    fit: BoxFit.cover,
                  ),
                  // boxShadow: boxShadow,
                  borderRadius: BorderRadius.circular(
                      (size + borderWidth * 2) / (size / radius)),
                )
              : null,
          child: child == null
              ? null
              : Center(
                  child: MediaQuery(
                    // Need to ignore the ambient textScaleFactor here so that the
                    // text doesn't escape the avatar when the textScaleFactor is large.
                    data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
                    child: IconTheme(
                      data: theme.iconTheme.copyWith(color: textStyle.color),
                      child: DefaultTextStyle(
                        style: textStyle,
                        child: child!,
                      ),
                    ),
                  ),
                ),
        );
      }
    
      ImageProvider _buildImageProvider(imagePath) {
        Map<String, dynamic> imageInfo = HCFileUtil.checkAndFixImagePath(imagePath);
        HcImageType type = imageInfo['type'];
        imagePath = imageInfo['url'];
        ImageProvider imageProvider = AssetImage(imagePath);
        switch (type) {
          case HcImageType.assets:
            imageProvider = AssetImage(imagePath);
            break;
          case HcImageType.file:
            imageProvider = FileImage(File(imagePath));
            break;
          case HcImageType.base64:
            Uint8List bytes = const Base64Decoder().convert(imagePath);
            imageProvider = MemoryImage(bytes);
            break;
          case HcImageType.network:
            imageProvider = CachedNetworkImageProvider(imagePath);
            break;
        }
    
        return imageProvider;
      }
    }
    
    

    相关文章

      网友评论

          本文标题:Flutter 重复造轮子 (2) Avatar 头像显示组件的

          本文链接:https://www.haomeiwen.com/subject/cjybsdtx.html