import 'package:flutter/material.dart'; import '../theme.dart'; /// 头像(按效果图): /// - 单人是圆角方块 + 姓氏首字,蓝 / 灰蓝两色按名字 hash 取色; /// - 群聊是 2x2 小方块拼格; /// - 有 faceURL 时优先显示网络头像,加载失败回退到首字。 class NameAvatar extends StatelessWidget { final String name; final String? faceURL; final double size; /// 是否群聊样式(2x2 拼格) final bool isGroup; const NameAvatar({ super.key, required this.name, this.faceURL, this.size = 48, this.isGroup = false, }); Color _colorFor(String text) { var hash = 0; for (final code in text.codeUnits) { hash = (hash * 31 + code) & 0x7fffffff; } return hash % 2 == 0 ? AppColors.primary : AppColors.avatarGray; } @override Widget build(BuildContext context) { final radius = BorderRadius.circular(size * 0.18); if (isGroup) return _groupAvatar(radius); final hasFace = faceURL != null && faceURL!.isNotEmpty; final letter = name.isNotEmpty ? name.substring(0, 1) : ''; return ClipRRect( borderRadius: radius, child: Container( width: size, height: size, color: _colorFor(name), alignment: Alignment.center, child: hasFace ? Image.network( faceURL!, width: size, height: size, fit: BoxFit.cover, errorBuilder: (_, __, ___) => _letterText(letter), loadingBuilder: (_, child, progress) => progress == null ? child : _letterText(letter), ) : _letterText(letter), ), ); } Widget _letterText(String letter) { return Text( letter, style: TextStyle( color: Colors.white, fontSize: size * 0.4, fontWeight: FontWeight.w500, ), ); } /// 群头像:浅灰底上 2x2 小方块,蓝 / 灰蓝交替 Widget _groupAvatar(BorderRadius radius) { final cell = (size - 10) / 2; const colors = [AppColors.primary, AppColors.avatarGray, AppColors.avatarGray, AppColors.primary]; return ClipRRect( borderRadius: radius, child: Container( width: size, height: size, color: AppColors.searchBg, padding: const EdgeInsets.all(2), child: Wrap( spacing: 2, runSpacing: 2, children: List.generate( 4, (i) => Container( width: cell, height: cell, decoration: BoxDecoration( color: colors[i], borderRadius: BorderRadius.circular(2), ), ), ), ), ), ); } }