在颤振应用程序中仅选择一个复选框列表标题
Posted
技术标签:
【中文标题】在颤振应用程序中仅选择一个复选框列表标题【英文标题】:Selecting only one checkbox list title in flutter app 【发布时间】:2020-06-03 18:59:19 【问题描述】:我正在颤振中构建一个可选择的复选框联系人列表,但是当我点击单个联系人卡片时,它会选择所有联系人,而不仅仅是我点击的那个。请有人指导我解释我应该更改什么以允许一次只选择一个联系人磁贴?
我不知道从哪里开始。我想也许当它更新(默认为假)_isSelected 变量然后设置状态时,它正在为所有联系人设置新的(真)_isSelected 变量。但是,我刚开始使用颤振,所以我想不出如何解决这个问题。
这是我的代码
import 'package:flutter/material.dart';
// TODO: make it ask for permissions otherwise the app crashes
import 'package:contacts_service/contacts_service.dart';
class Home extends StatefulWidget
@override
_HomeState createState() => _HomeState();
class _HomeState extends State<Home>
List<Contact> contacts = [];
List<Contact> contactsFiltered = [];
TextEditingController searchController = new TextEditingController();
@override
void initState()
super.initState();
getAllContacts();
searchController.addListener(() => filterContacts());
String flattenPhoneNumber(String phoneStr)
return phoneStr.replaceAllMapped(RegExp(r'^(\+)|\D'), (Match m)
return m[0] == "+" ? "+" : "";
);
filterContacts()
List<Contact> _contacts = [];
_contacts.addAll(contacts);
if (searchController.text.isNotEmpty)
_contacts.retainWhere((contact)
String searchTerm = searchController.text.toLowerCase();
String searchTermFlatten = flattenPhoneNumber(searchTerm);
String contactName = contact.displayName.toLowerCase();
bool nameMatches = contactName.contains(searchTerm);
var phone = contact.phones.firstWhere((phn)
String phnFlattened = flattenPhoneNumber(phn.value);
return phnFlattened.contains(searchTerm);
, orElse: () => null);
if (searchTermFlatten.isEmpty)
return false;
if (nameMatches == true)
return true;
return phone != null;
);
setState(()
contactsFiltered = _contacts;
);
bool _isSelected = false;
getAllContacts() async
Iterable<Contact> _contacts = (await ContactsService.getContacts()).toList();
setState(()
contacts = _contacts;
);
int _currentIndex = 0;
final tabs = [
Center(child: Text('Create New')),
Center(child: Text('Click to confirm group creation')),
];
@override
Widget build(BuildContext context)
bool isSearching = searchController.text.isNotEmpty;
return Scaffold(
body: SafeArea(
child: Column(
children: <Widget>[
AppBar(
title: Text('Create Group'),
),
Container(
child: TextField(
controller: searchController,
decoration: InputDecoration(
labelText: 'Search Contacts',
border: OutlineInputBorder(
borderSide: new BorderSide(
color: Theme.of(context).primaryColor
)
),
prefixIcon: Icon(
Icons.search,
color: Theme.of(context).primaryColor
)
),
),
),
Expanded( child: ListView.builder(
shrinkWrap: true,
itemCount: isSearching == true ? contactsFiltered.length : contacts.length,
itemBuilder: (context, index)
Contact contact = isSearching == true ? contactsFiltered[index] : contacts[index];
//TODO: make it so when you clear your search, all items appear again
return CheckboxListTile(
title: Text(contact.displayName),
subtitle: Text(contact.phones.elementAt(0).value),
value: _isSelected,
onChanged: (bool value)
setState(()
_isSelected = value;
// TODO: add in function to add contact ID to a list
//TODO: make it so that you can select a single one not just all
);
,
)
;
,
),
),
new Expanded(
child: Align(
alignment: Alignment.bottomLeft,
child: BottomNavigationBar(
currentIndex: _currentIndex,
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.add),
title: Text('Add Contact'),
),
BottomNavigationBarItem(
icon: Icon(Icons.create),
title: Text('Create Group'),
),
],
onTap: (index)
setState(()
_currentIndex = index;
);
)
)
)
],
)
),
);
【问题讨论】:
您有 N 个联系人,但只有一个isSelected
变量,这就是为什么您不能使用一个布尔变量来表示 N 个选定状态
【参考方案1】:
您有list
(多个)联系人和single
变量_isSelected
,它控制CheckboxListTile
的所有选定状态
如果您的用例是选择任意数量的联系人 - 您需要保持每个联系人的选定状态
方法不止一种,试试下一种
-
跟踪所有选定的联系人
检查是否选择了联系人并将结果设置为
value:
在onChanged:
回调中添加或删除联系人
final selectedContacts = Set<Contact>();
...
itemBuilder: (context, index)
Contact contact = isSearching == true ? contactsFiltered[index] : contacts[index];
//TODO: make it so when you clear your search, all items appear again
return CheckboxListTile(
title: Text(contact.displayName),
subtitle: Text(contact.phones.elementAt(0).value),
value: selectedContacts.contains(contact),
onChanged: (bool value)
if (value)
selectedContacts.add(contact);
else
selectedContacts.remove(contact);
setState(());
...
【讨论】:
非常感谢,我现在得到的唯一问题是关于 ` if (value) selectedContacts.add(contact); ` (contact) 收到错误消息“无法将参数类型 'Contact' 分配给参数类型 'int'.dartargument_type_not_assignable' 未来我建议你学习状态管理flutter.dev/docs/development/data-and-backend/state-mgmt 太棒了。谢谢你!我刚开始使用颤振和编程,所以我会看看。 如果回答对您有帮助,如果您接受并评价它,我将不胜感激 =) 已接受答案。我不能把它评为我以上是关于在颤振应用程序中仅选择一个复选框列表标题的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 jquery 从 asp.net 列表框中仅获取当前选定的选项