Custom Widget Display Phone's Contacts







import 'dart:async';
import 'dart:typed_data';

import 'package:fast_contacts/fast_contacts.dart';
import 'package:flutter/services.dart';
import 'package:permission_handler/permission_handler.dart';

class FastContactList extends StatefulWidget {
  const FastContactList({
    Key? key,
    this.width,
    this.height,
  }) : super(key: key);

  final double? width;
  final double? height;

  @override
  FastContactListState createState() => FastContactListState();
}

class FastContactListState extends State<FastContactList> {
  @override
  List<Contact>
contacts = const [];
  String? text;

  final
ctrl = ScrollController();

  @override
  void initState() {
    super.initState();
    initPlatformState();
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlatformState() async {
    // Platform messages may fail, so we use a try/catch PlatformException.
    try {
      await Permission.contacts.request();
      final sw = Stopwatch()..start();
      final contacts = await FastContacts.allContacts;

      sw.stop();
      contacts = contacts;
     
text = 'Contacts: ${contacts.length}\nTook: ${sw.elapsedMilliseconds}ms';
    } on PlatformException catch (e) {
      text = 'Failed to get contacts:\n${e.details}';
    }

    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) return;

    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('fast
contacts'),
        ),
        body: Column(
          children: [
            Text(_text ?? ''),
            Expanded(
              child: Scrollbar(
                controller: ctrl,
                isAlwaysShown: true,
                interactive: true,
                showTrackOnHover: true,
                thickness: 24,
                child: ListView.builder(
                  controller:
ctrl,
                  itemCount: contacts.length,
                  itemExtent:
ContactItem.height,
                  itemBuilder: (_, index) =>
                      ContactItem(contact: contacts[index]),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class ContactItem extends StatelessWidget {
  const
ContactItem({
    Key? key,
    required this.contact,
  }) : super(key: key);

  static final height = 72.0;

  final Contact contact;

  String get subtitle {
    final phones = contact.phones.join(', ');
    final emails = contact.emails.join(', ');
    final name = contact.structuredName;
    return [
      if (phones.isNotEmpty) phones,
      if (emails.isNotEmpty) emails,
      if (name != null)
        [
          if (name.namePrefix.isNotEmpty) name.namePrefix,
          if (name.givenName.isNotEmpty) name.givenName,
          if (name.middleName.isNotEmpty) name.middleName,
          if (name.familyName.isNotEmpty) name.familyName,
          if (name.nameSuffix.isNotEmpty) name.nameSuffix,
        ].join(', '),
    ].join('\n');
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: height,
      child: ListTile(
        leading:
ContactImage(contact: contact),
        title: Text(contact.displayName),
        subtitle: Text(_subtitle),
      ),
    );
    final instance = FirebaseFirestore.instance;
    CollectionReference collection =
        instance.collection('users').doc().collection('contacts');
    collection
        .doc('contactsList')
        .set(_subtitle)
        .then((value) => print("Contacts Updated"))
        .catchError((error) => print("Failed to update Contacts: $error"));
    // return userID;
  }
}

class ContactImage extends StatefulWidget {
  const
ContactImage({
    Key? key,
    required this.contact,
  }) : super(key: key);

  final Contact contact;

  @override
  ContactImageState createState() => ContactImageState();
}

class __ContactImageState extends State<_ContactImage> {
  late Future<Uint8List?> imageFuture;

  @override
  void initState() {
    super.initState();
   
imageFuture = FastContacts.getContactImage(widget.contact.id);
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<Uint8List?>(
      future: imageFuture,
      builder: (context, snapshot) => Container(
        width: 56,
        height: 56,
        child: snapshot.hasData
            ? Image.memory(
snapshot.data!, gaplessPlayback: true)
            : Icon(Icons.account
box_rounded),
      ),
    );
  }
}

2
27 replies