import 'package:azlistview/azlistview.dart'; import 'package:flutter/material.dart'; import 'package:lpinyin/lpinyin.dart'; import 'package:sweet_chat_app/apis/user_api.dart'; import 'package:sweet_chat_app/models/contact_info.dart'; import 'package:sweet_chat_app/models/user.dart'; import 'package:sweet_chat_app/utils/sp_utils.dart'; import 'chat_page.dart'; class ContactsPage extends StatefulWidget { const ContactsPage({super.key}); @override State createState() => _ContactsPageState(); } class _ContactsPageState extends State { List contactList = []; @override void initState() { super.initState(); _loadFriends(); } Future _loadFriends() async { final userId = SpUtil.getInt('userId') ?? 0; final friendList = await getUserFriendsApi(userId); setState(() { _handleList(friendList); }); } void _handleList(List friends) { contactList = friends.map((user) { final pinyin = PinyinHelper.getPinyinE(user.nickname); final tag = pinyin.substring(0, 1).toUpperCase(); return ContactInfo( id: user.id, name: user.nickname, avatar: user.avatarUrl, tagIndex: RegExp(r'^[A-Z]$').hasMatch(tag) ? tag : '#', namePinyin: pinyin, ); }).toList(); SuspensionUtil.sortListBySuspensionTag(contactList); SuspensionUtil.setShowSuspensionStatus(contactList); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.transparent, appBar: _buildAppBar(), body: Column( children: [_buildSearchBar(), Expanded(child: _buildAzListView())], ), ); } PreferredSizeWidget _buildAppBar() { return AppBar( automaticallyImplyLeading: false, backgroundColor: Color(0xFF120D25), elevation: 0, centerTitle: true, title: const Text( '通讯录', style: TextStyle( fontSize: 18, fontWeight: FontWeight.w600, color: Colors.white, ), ), ); } Widget _buildAzListView() { return AzListView( data: contactList, itemCount: contactList.length, itemBuilder: (_, index) { final contact = contactList[index]; return ListTile( leading: CircleAvatar( backgroundImage: NetworkImage(contact.avatar), onBackgroundImageError: (_, __) {}, ), title: Text( contact.name, style: const TextStyle(fontSize: 16, color: Colors.white), ), onTap: () => onTapContact(contact), ); }, susItemBuilder: (_, index) { final tag = contactList[index].getSuspensionTag(); return Container( height: 28, padding: const EdgeInsets.symmetric(horizontal: 16), alignment: Alignment.centerLeft, color: const Color(0xFF2B2744), child: Text( tag, style: const TextStyle(fontSize: 13, color: Colors.grey), ), ); }, indexBarData: [...kIndexBarData], indexBarOptions: IndexBarOptions( textStyle: const TextStyle(fontSize: 12, color: Color(0xFF8E8E93)), selectItemDecoration: const BoxDecoration( shape: BoxShape.circle, color: Colors.green, ), ), ); } Widget _buildSearchBar() { return Container( height: 44, decoration: BoxDecoration(color: Color(0xFF2F2A47)), child: TextField( textAlignVertical: TextAlignVertical.center, style: const TextStyle(color: Colors.white), decoration: InputDecoration( isDense: true, hintText: '搜索联系人', hintStyle: const TextStyle(fontSize: 15, color: Colors.white), prefixIcon: const Icon(Icons.search, size: 20, color: Colors.white), border: InputBorder.none, ), ), ); } void onTapContact(ContactInfo contact) { Navigator.push( context, MaterialPageRoute(builder: (_) => ChatPage(contactInfo: contact, conversationId: 0)), ); } }