You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
137 lines
3.7 KiB
137 lines
3.7 KiB
import 'dart:io';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
import 'package:get/get.dart';
|
|
import '../controllers/profile_controller.dart';
|
|
|
|
/// 统一头像显示组件
|
|
/// 确保所有页面的头像显示逻辑一致,避免闪烁问题
|
|
class UnifiedAvatar extends StatelessWidget {
|
|
final double radius;
|
|
final Color? backgroundColor;
|
|
final Color? iconColor;
|
|
final double? iconSize;
|
|
final bool isDarkMode;
|
|
final VoidCallback? onTap;
|
|
|
|
const UnifiedAvatar({
|
|
super.key,
|
|
required this.radius,
|
|
this.backgroundColor,
|
|
this.iconColor,
|
|
this.iconSize,
|
|
this.isDarkMode = false,
|
|
this.onTap,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final ProfileController profileCtrl = Get.find<ProfileController>();
|
|
|
|
return GestureDetector(
|
|
onTap: onTap,
|
|
child: Obx(() {
|
|
// 等待头像数据准备完成,避免闪烁
|
|
if (!profileCtrl.isAvatarReady.value) {
|
|
return _buildLoadingAvatar();
|
|
}
|
|
|
|
return _buildAvatar(profileCtrl);
|
|
}),
|
|
);
|
|
}
|
|
|
|
/// 构建加载中的头像占位符
|
|
Widget _buildLoadingAvatar() {
|
|
return CircleAvatar(
|
|
radius: radius,
|
|
backgroundColor:
|
|
backgroundColor ?? (isDarkMode ? Colors.grey[800] : Colors.grey[200]),
|
|
child: Icon(
|
|
Icons.person,
|
|
size: iconSize ?? (radius * 0.6),
|
|
color: iconColor ?? (isDarkMode ? Colors.grey[400] : Colors.grey[600]),
|
|
),
|
|
);
|
|
}
|
|
|
|
/// 构建实际头像
|
|
Widget _buildAvatar(ProfileController profileCtrl) {
|
|
ImageProvider<Object>? imageProvider;
|
|
|
|
// 统一头像显示优先级:本地头像 > 网络头像 > 默认图标
|
|
if (profileCtrl.localAvatar.value.isNotEmpty) {
|
|
imageProvider = FileImage(File(profileCtrl.localAvatar.value));
|
|
} else if (profileCtrl.userInfo.value.avatar.isNotEmpty) {
|
|
imageProvider = NetworkImage(profileCtrl.userInfo.value.avatar);
|
|
}
|
|
|
|
return CircleAvatar(
|
|
radius: radius,
|
|
backgroundImage: imageProvider,
|
|
backgroundColor:
|
|
backgroundColor ?? (isDarkMode ? Colors.grey[800] : Colors.grey[200]),
|
|
child: (profileCtrl.localAvatar.value.isEmpty &&
|
|
profileCtrl.userInfo.value.avatar.isEmpty)
|
|
? Icon(
|
|
Icons.person,
|
|
size: iconSize ?? (radius * 0.6),
|
|
color: iconColor ??
|
|
(isDarkMode ? Colors.grey[400] : Colors.grey[600]),
|
|
)
|
|
: null,
|
|
);
|
|
}
|
|
}
|
|
|
|
/// 带容器装饰的统一头像组件
|
|
class UnifiedAvatarWithContainer extends StatelessWidget {
|
|
final double width;
|
|
final double height;
|
|
final double radius;
|
|
final Color? backgroundColor;
|
|
final Color? iconColor;
|
|
final double? iconSize;
|
|
final bool isDarkMode;
|
|
final VoidCallback? onTap;
|
|
final EdgeInsetsGeometry? margin;
|
|
final List<BoxShadow>? boxShadow;
|
|
|
|
const UnifiedAvatarWithContainer({
|
|
super.key,
|
|
required this.width,
|
|
required this.height,
|
|
required this.radius,
|
|
this.backgroundColor,
|
|
this.iconColor,
|
|
this.iconSize,
|
|
this.isDarkMode = false,
|
|
this.onTap,
|
|
this.margin,
|
|
this.boxShadow,
|
|
});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Container(
|
|
width: width,
|
|
height: height,
|
|
margin: margin,
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(radius),
|
|
boxShadow: boxShadow,
|
|
),
|
|
child: ClipRRect(
|
|
borderRadius: BorderRadius.circular(radius),
|
|
child: UnifiedAvatar(
|
|
radius: radius / 2,
|
|
backgroundColor: backgroundColor,
|
|
iconColor: iconColor,
|
|
iconSize: iconSize,
|
|
isDarkMode: isDarkMode,
|
|
onTap: onTap,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|