颤动中的自定义联系人选择

Custom contact selection in flutter

我在 flutter 中创建了一个应用程序,其中我的设备的所有联系人都在 flutter 应用程序中检索。我想 select 几个联系人。但是当我 select 任何一个联系人时,所有联系人都被 selected。如果有人可以通过更改我的代码来帮助我,那将是一个很大的帮助。

源代码:

import 'package:contacts_app/checkbox.dart';
import 'package:flutter/material.dart';
import 'package:contacts_service/contacts_service.dart';
import 'package:contacts_app/smsButton.dart';
import 'package:contacts_app/phoneButton.dart';

class ContactsPage extends StatefulWidget {
  @override
  _ContactsPageState createState() => _ContactsPageState();
}

class _ContactsPageState extends State<ContactsPage> {
  Iterable<Contact> _contacts=[];
  bool value = false;

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

  Future<void> getContacts() async {
    //We already have permissions for contact when we get to this page, so we
    // are now just retrieving it
    final Iterable<Contact> contacts = await ContactsService.getContacts();
    setState(() {
      _contacts = contacts;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _contacts != null
          //Build a list view of all contacts, displaying their avatar and
          // display name
          ? ListView.builder(
              itemCount: _contacts?.length ?? 0,
              itemBuilder: (BuildContext context, int index) {
                Contact contact = _contacts?.elementAt(index);
                return ListTile(
                    contentPadding:
                      const EdgeInsets.symmetric(vertical: 2, horizontal: 18),
                  leading: (contact.avatar != null && contact.avatar.isNotEmpty)
                      ? CircleAvatar(
                          backgroundImage: MemoryImage(contact.avatar),
                        )
                      : CircleAvatar(
                          child: Text(contact.initials()),
                          backgroundColor: Theme.of(context).accentColor,
                        ),
                  title: Text(contact.displayName ?? ''),
                  //This can be further expanded to showing contacts detail
                  // onPressed().
                  trailing: Row(
                    mainAxisSize: MainAxisSize.min,
                    children: <Widget>[
                      PhoneButton(phoneNumbers: contact.phones),
                      SmsButton(phoneNumbers: contact.phones),
                      buildCheckbox()
                    ],
                  ),

                );
              },
            )
          : Center(child: const CircularProgressIndicator()),
    );
  }

  Widget buildCheckbox()=>Checkbox(
    value: value,
    onChanged: (value){
        setState(() {
          this.value=value;
        },
      );

    },
  );
}

Image of issue

ContactsPage 的状态包含一个布尔值 bool value = false;

当你 select any 联系人时,这个布尔值在你的状态下被翻转为 true,导致重建所有复选框,它们都使用这个相同的值:所有都是 selected.

解决此问题的一种方法是为每个联系人维护一个布尔值 selected。在代码中,类似于:

List<bool> value = [];

加载联系人时,您可以用布尔值填充此列表。

Future<void> getContacts() async {
    //We already have permissions for contact when we get to this page, so we
    // are now just retrieving it
    final Iterable<Contact> contacts = await ContactsService.getContacts();
    setState(() {
      _contacts = contacts;

      // initialize the list of booleans to track which contacts are/aren't selected
      value = contacts.map((e) => false).toList();
    });
  }

然后您可以编辑 buildCheckbox 函数以获取索引,并查看和操作该索引处的布尔值:

Widget buildCheckbox(int index)=>Checkbox(
    value: value[index],
    onChanged: (value){
        setState(() {
          this.value[index]=value;
        },
      );

    },
  );

因此,当您更改复选框的值时(通过 checking/unchecking 它),只会更新单个复选框的值。

或者,如果您一次只需要 selected 一个联系人(更像是一个单选按钮),您可以保留一个整数来表示当前正在 selected 哪个联系人。这更简单,但实际上取决于您想要实现的目标。

获取一个新列表并检查该列表是否存在该索引项如果不存在则添加它如果该索引项存在然后删除它。

List<String> SelectedContact=[];


List<ContactModel>state;//thats contacts list 

Checkbox(
                                value:SelectedContact.contains(state[index].phnono),
                                onChanged: (bool newValue) {
                              if(newValue)
                                {
                                  SelectedContact.add(state[index].phno);
                               
                                }
                              else
                                {
                                  SelectedContact.remove(state[index].phnono);
                                
                                }
                                state[index].ischecked=newValue;
                                },

                              ),