Files
sweet_chat_app/lib/pages/contacts_page.dart
2026-06-16 23:26:12 +08:00

233 lines
6.2 KiB
Dart

import 'package:azlistview/azlistview.dart';
import 'package:flutter/material.dart';
import 'package:lpinyin/lpinyin.dart';
class ContactInfo extends ISuspensionBean {
final String name;
final String avatar;
String? tagIndex;
String? namePinyin;
ContactInfo({
required this.name,
required this.avatar,
this.tagIndex,
this.namePinyin,
});
@override
String getSuspensionTag() => tagIndex ?? '#';
}
/// ================= Page =================
class ContactsPage extends StatefulWidget {
const ContactsPage({super.key});
@override
State<ContactsPage> createState() => _ContactsPageState();
}
class _ContactsPageState extends State<ContactsPage> {
List<ContactInfo> contactList = [];
List<ContactInfo> topList = [];
@override
void initState() {
super.initState();
_loadFakeData();
}
void _loadFakeData() {
contactList = [
ContactInfo(
name: '张三',
avatar: 'https://randomuser.me/api/portraits/men/11.jpg',
),
ContactInfo(
name: '李四',
avatar: 'https://randomuser.me/api/portraits/men/12.jpg',
),
ContactInfo(
name: '王五',
avatar: 'https://randomuser.me/api/portraits/men/13.jpg',
),
ContactInfo(
name: '赵六',
avatar: 'https://randomuser.me/api/portraits/women/14.jpg',
),
ContactInfo(
name: '陈七',
avatar: 'https://randomuser.me/api/portraits/women/15.jpg',
),
ContactInfo(
name: '刘八',
avatar: 'https://randomuser.me/api/portraits/men/16.jpg',
),
ContactInfo(
name: '周九',
avatar: 'https://randomuser.me/api/portraits/men/17.jpg',
),
ContactInfo(
name: '吴十',
avatar: 'https://randomuser.me/api/portraits/women/18.jpg',
),
ContactInfo(
name: '欧阳峰',
avatar: 'https://randomuser.me/api/portraits/men/21.jpg',
),
ContactInfo(
name: '诸葛青',
avatar: 'https://randomuser.me/api/portraits/men/22.jpg',
),
ContactInfo(
name: '司马光',
avatar: 'https://randomuser.me/api/portraits/men/23.jpg',
),
ContactInfo(
name: '慕容复',
avatar: 'https://randomuser.me/api/portraits/women/24.jpg',
),
ContactInfo(
name: '安琪拉',
avatar: 'https://randomuser.me/api/portraits/women/31.jpg',
),
ContactInfo(
name: '亚瑟',
avatar: 'https://randomuser.me/api/portraits/men/32.jpg',
),
ContactInfo(
name: '李白',
avatar: 'https://randomuser.me/api/portraits/men/33.jpg',
),
ContactInfo(
name: '韩信',
avatar: 'https://randomuser.me/api/portraits/men/34.jpg',
),
ContactInfo(
name: '孙尚香',
avatar: 'https://randomuser.me/api/portraits/women/35.jpg',
),
ContactInfo(
name: '鲁班',
avatar: 'https://randomuser.me/api/portraits/men/36.jpg',
),
ContactInfo(
name: '妲己',
avatar: 'https://randomuser.me/api/portraits/women/37.jpg',
),
ContactInfo(
name: '甄姬',
avatar: 'https://randomuser.me/api/portraits/women/38.jpg',
),
];
_handleList(contactList);
}
void _handleList(List<ContactInfo> list) {
for (var item in list) {
final pinyin = PinyinHelper.getPinyinE(item.name);
final tag = pinyin.substring(0, 1).toUpperCase();
item.namePinyin = pinyin;
item.tagIndex = RegExp(r'[A-Z]').hasMatch(tag) ? tag : '#';
}
SuspensionUtil.sortListBySuspensionTag(list);
SuspensionUtil.setShowSuspensionStatus(list);
setState(() {});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xFFF2F2F7),
appBar: AppBar(
automaticallyImplyLeading: false,
backgroundColor: Colors.grey.shade200,
elevation: 0,
centerTitle: true,
title: const Text(
'通讯录',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Color(0xFF1C1C1E),
),
),
),
body: Column(
children: [_buildSearchBar(), Expanded(child: _buildAzListView())],
),
);
}
Widget _buildAzListView() {
return AzListView(
data: contactList,
itemCount: contactList.length,
itemBuilder: (_, index) {
final c = contactList[index];
return Container(
color: Colors.white,
child: ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage(c.avatar),
onBackgroundImageError: (_, __) {},
),
title: Text(
c.name,
style: const TextStyle(fontSize: 16, color: Color(0xFF1C1C1E)),
),
),
);
},
susItemBuilder: (_, index) {
final tag = contactList[index].getSuspensionTag();
return Container(
height: 28,
padding: const EdgeInsets.symmetric(horizontal: 16),
alignment: Alignment.centerLeft,
color: const Color(0xFFF2F2F7),
child: Text(
tag,
style: const TextStyle(fontSize: 13, color: Color(0xFF8E8E93)),
),
);
},
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: Colors.white,
),
child: TextField(
textAlignVertical: TextAlignVertical.center,
decoration: InputDecoration(
hintText: '搜索联系人',
hintStyle: const TextStyle(fontSize: 15, color: Color(0xFF8E8E93)),
prefixIcon: const Icon(
Icons.search,
size: 20,
color: Color(0xFF8E8E93),
),
border: InputBorder.none,
contentPadding: const EdgeInsets.symmetric(vertical: 12),
),
),
);
}
}