99 lines
3.3 KiB
Dart
99 lines
3.3 KiB
Dart
import 'package:dialer/widgets/username_color_generator.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_contacts/flutter_contacts.dart';
|
|
import '../contact_state.dart';
|
|
|
|
class AlphabetScrollPage extends StatefulWidget {
|
|
final List<Contact> contacts;
|
|
final double scrollOffset;
|
|
|
|
const AlphabetScrollPage({Key? key, required this.contacts, required this.scrollOffset}) : super(key: key);
|
|
|
|
@override
|
|
_AlphabetScrollPageState createState() => _AlphabetScrollPageState();
|
|
}
|
|
|
|
class _AlphabetScrollPageState extends State<AlphabetScrollPage> {
|
|
late ScrollController _scrollController;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_scrollController = ScrollController(initialScrollOffset: widget.scrollOffset);
|
|
_scrollController.addListener(_onScroll);
|
|
}
|
|
|
|
void _onScroll() {
|
|
final contactState = ContactState.of(context);
|
|
contactState.setScrollOffset(_scrollController.offset);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
Map<String, List<Contact>> alphabetizedContacts = {};
|
|
for (var contact in widget.contacts) {
|
|
String firstLetter = contact.displayName.isNotEmpty ? contact.displayName[0].toUpperCase() : '#';
|
|
if (!alphabetizedContacts.containsKey(firstLetter)) {
|
|
alphabetizedContacts[firstLetter] = [];
|
|
}
|
|
alphabetizedContacts[firstLetter]!.add(contact);
|
|
}
|
|
|
|
List<String> alphabetKeys = alphabetizedContacts.keys.toList()..sort();
|
|
|
|
return ListView.builder(
|
|
controller: _scrollController,
|
|
itemCount: alphabetKeys.length,
|
|
itemBuilder: (context, index) {
|
|
String letter = alphabetKeys[index];
|
|
List<Contact> contacts = alphabetizedContacts[letter]!;
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Container(
|
|
color: Colors.grey[300],
|
|
width: double.infinity,
|
|
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
|
|
child: Text(
|
|
letter,
|
|
style: TextStyle(
|
|
fontSize: 18,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
),
|
|
...contacts.map((contact) {
|
|
String phoneNumber = contact.phones.isNotEmpty ? contact.phones.first.number : 'No phone number';
|
|
Color avatarColor = generateColorFromName(contact.displayName);
|
|
return ListTile(
|
|
leading: (contact.thumbnail != null && contact.thumbnail!.isNotEmpty)
|
|
? CircleAvatar(
|
|
backgroundImage: MemoryImage(contact.thumbnail!),
|
|
)
|
|
: CircleAvatar(
|
|
backgroundColor: avatarColor,
|
|
child: Text(
|
|
contact.displayName.isNotEmpty ? contact.displayName[0].toUpperCase() : '?',
|
|
style: TextStyle(color: Colors.white),
|
|
),
|
|
),
|
|
title: Text(contact.displayName),
|
|
subtitle: Text(phoneNumber),
|
|
onTap: () {
|
|
// Handle contact tap
|
|
},
|
|
);
|
|
}).toList(),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_scrollController.dispose();
|
|
super.dispose();
|
|
}
|
|
}
|