| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- import 'package:cached_network_image/cached_network_image.dart';
- import 'package:flutter/material.dart';
- /// 圆形头像组件
- class CircleAvatarWidget extends StatelessWidget {
- /// 本地图片
- final ImageProvider? image;
- /// 网络图片URL
- final String? imageUrl;
- /// 加载失败时的占位图
- final ImageProvider? placeholderImage;
- /// 头像大小
- final double size;
- /// 边框颜色
- final Color borderColor;
- /// 边框宽度
- final double borderWidth;
- /// 背景颜色
- final Color backgroundColor;
- /// 加载时的渐变时长
- final Duration fadeInDuration;
- /// 加载中的占位
- final PlaceholderWidgetBuilder? placeholder;
- const CircleAvatarWidget({
- super.key,
- this.image,
- this.imageUrl,
- this.placeholderImage,
- this.size = 40.0,
- this.borderColor = Colors.white,
- this.borderWidth = 2.0,
- this.backgroundColor = const Color(0xFFEEEEEE),
- this.fadeInDuration = const Duration(milliseconds: 500),
- this.placeholder,
- });
- @override
- Widget build(BuildContext context) {
- return Container(
- width: size,
- height: size,
- decoration: BoxDecoration(
- shape: BoxShape.circle,
- border: Border.all(color: borderColor, width: borderWidth),
- ),
- // 裁切圆形
- child: ClipOval(child: _buildContent()),
- );
- }
- /// 构建头像内容
- Widget _buildContent() {
- // 优先使用网络图片
- if (imageUrl != null && imageUrl!.isNotEmpty) {
- return CachedNetworkImage(
- imageUrl: imageUrl!,
- width: size,
- height: size,
- fit: BoxFit.cover,
- fadeInDuration: fadeInDuration,
- placeholder: placeholder ?? _buildLoadingPlaceholder,
- errorWidget: (_, __, ___) => _buildPlaceholder(), // 错误时显示占位
- );
- }
- // 没有,再使用本地图片
- else if (image != null) {
- return Image(
- image: image!,
- width: size,
- height: size,
- fit: BoxFit.cover,
- errorBuilder: (_, __, ___) => _buildPlaceholder(),
- );
- }
- // 无图片状态
- else {
- return _buildPlaceholder();
- }
- }
- /// 加载中占位
- Widget _buildLoadingPlaceholder(BuildContext context, String url) {
- return Container(
- color: Colors.grey[200],
- alignment: Alignment.center,
- child: const CircularProgressIndicator(strokeWidth: 2),
- );
- }
- /// 错误/默认的占位组件
- Widget _buildPlaceholder() {
- // 优先使用自定义占位图
- if (placeholderImage != null) {
- return Image(
- image: placeholderImage!,
- width: size,
- height: size,
- fit: BoxFit.cover,
- // 占位图加载失败时,显示一个纯色背景
- errorBuilder: (_, __, ___) => _buildDefaultPlaceholder(),
- );
- }
- // 默认占位
- return _buildDefaultPlaceholder();
- }
- /// 占位图加载失败时,显示一个纯色背景
- Widget _buildDefaultPlaceholder() {
- return Container(color: backgroundColor, width: size, height: size);
- }
- }
|