我正在尝试使用contact services从移动设备获取联系人,我正在正确计数所有联系人,但未在ListView上显示联系人。它给了我以下错误。
I/flutter (18134): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (18134): The following RangeError was thrown building:
I/flutter (18134): RangeError (index): Invalid value: Valid value range is empty: 0
I/flutter (18134):
I/flutter (18134): When the exception was thrown, this was the stack:
I/flutter (18134): #0 List.[] (dart:core-patch/array.dart:16:52)
I/flutter (18134): #1 ListMixin.elementAt (dart:collection/list.dart:61:33)
I/flutter (18134): #2 MappedListIterable.elementAt (dart:_internal/iterable.dart:417:40)
I/flutter (18134): #3 _ContactPageState.contactListView.<anonymous closure> (package:private_call/contact_screen.dart:134:55)
I/flutter (18134): #4 SliverChildBuilderDelegate.build (package:flutter/src/widgets/sliver.dart:446:22)
I/flutter (18134): #5 SliverMultiBoxAdaptorElement._build.<anonymous closure> (package:flutter/src/widgets/sliver.dart:1134:67)
I/flutter (18134): #6 _HashMap.putIfAbsent (dart:collection-patch/collection_patch.dart:139:29)
I/flutter (18134): #7 SliverMultiBoxAdaptorElement._build (package:flutter/src/widgets/sliver.dart:1134:26)
I/flutter (18134): #8 SliverMultiBoxAdaptorElement.createChild.<anonymous closure> (package:flutter/src/widgets/sliver.dart:1147:55)
I/flutter (18134): #9 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2607:19)
I/flutter (18134): #10 SliverMultiBoxAdaptorElement.createChild (package:flutter/src/widgets/sliver.dart:1140:11)
I/flutter (18134): #11 RenderSliverMultiBoxAdaptor._createOrObtainChild.<anonymous closure> (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:354:23)
I/flutter (18134): #12 RenderObject.invokeLayoutCallback.<anonymous closure> (package:flutter/src/rendering/object.dart:1866:58)
I/flutter (18134): #13 PipelineOwner._enableMutationsToDirtySubtrees (package:flutter/src/rendering/object.dart:918:15)
I/flutter (18134): #14 RenderObject.invokeLayoutCallback (package:flutter/src/rendering/object.dart:1866:13)
I/flutter (18134): #15 RenderSliverMultiBoxAdaptor._createOrObtainChild (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:343:5)
I/flutter (18134): #16 RenderSliverMultiBoxAdaptor.insertAndLayoutChild (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:489:5)
I/flutter (18134): #17 RenderSliverList.performLayout.advance (package:flutter/src/rendering/sliver_list.dart:219:19)
I/flutter (18134): #18 RenderSliverList.performLayout (package:flutter/src/rendering/sliver_list.dart:262:19)
I/flutter (18134): #19 RenderObject.layout (package:flutter/src/rendering/object.dart:1767:7)
I/flutter (18134): #20 RenderSliverEdgeInsetsPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:135:11)
I/flutter (18134): #21 RenderSliverPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:375:11)
I/flutter (18134): #22 RenderObject.layout (package:flutter/src/rendering/object.dart:1767:7)
I/flutter (18134): #23 RenderViewportBase.layoutChildSequence (package:flutter/src/rendering/viewport.dart:452:13)
I/flutter (18134): #24 RenderShrinkWrappingViewport._attemptLayout (package:flutter/src/rendering/viewport.dart:1783:12)
I/flutter (18134): #25 RenderShrinkWrappingViewport.performLayout (package:flutter/src/rendering/viewport.dart:1741:20)
I/flutter (18134): #26 RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1630:7)
I/flutter (18134): #27 PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:887:18)
I/flutter (18134): #28 RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:402:19)
I/flutter (18134): #29 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:884:13)
I/flutter (18134): #30 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:284:5)
I/flutter (18134): #31 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1113:15)
I/flutter (18134): #32 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1052:9)
I/flutter (18134): #33 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:968:5)
I/flutter (18134): #37 _invoke (dart:ui/hooks.dart:261:10)
I/flutter (18134): #38 _drawFrame (dart:ui/hooks.dart:219:3)
I/flutter (18134): (elided 3 frames from dart:async)
I/flutter (18134): ════════════════════════════════════════════════════════════════════════════════════════════════════
我在Contacts Service构造函数中添加了isSearching布尔值,为每个联系人分配了错误的布尔值。
这是我的代码
import 'package:contacts_service/contacts_service.dart';
import 'package:flutter/material.dart';
import 'package:private_call/appBar.dart';
import 'cards_1.dart';
class ContactPage extends StatefulWidget {
@override
_ContactPageState createState() => _ContactPageState();
}
class _ContactPageState extends State<ContactPage> {
Color primaryColorButton = Color(0xFF4C4F5E);
Icon changeIcon = Icon(Icons.add);
String private_call = 'Private Call';
// bool selected = false;
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() {
setState(() {
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);
if (nameMatches == true) {
return true;
}
if (searchTermFlatten.isEmpty) {
return false;
}
var phone = contact.phones.firstWhere((phn) {
String phnFlattened = flattenPhoneNumber(phn.value);
return phnFlattened.contains(searchTermFlatten);
}, orElse: () => null);
return phone != null;
},
);
contactsFiltered = _contacts;
}
});
}
getAllContacts() async {
List<Contact> _contacts = (await ContactsService.getContacts()).toList();
setState(() {
contacts = _contacts;
});
}
@override
Widget build(BuildContext context) {
bool isSearching = searchController.text.isNotEmpty;
return Scaffold(
backgroundColor: Theme.of(context).primaryColor,
body: Column(
children: <Widget>[
AppbarCustom(
tMain: private_call,
),
Expanded(
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
searchBar(context),
contactListView(isSearching),
]),
),
),
],
),
);
}
Expanded contactListView(bool isSearching) {
return Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount:
isSearching == true ? contactsFiltered.length : contacts.length,
itemBuilder: (context, index) {
Contact contact =
isSearching == true ? contactsFiltered[index] : contacts[index];
return ListTile(
onTap: () {
// print(contact.isSelected);
// print(contact.phones.elementAt(0).value);
setState(() {
(!contacts[index].isSelected)
? contacts[index].isSelected = true
: contacts[index].isSelected = false;
});
print(index);
print(contacts[index].isSelected);
},
selected: contacts[index].isSelected,
title: Text(contact.displayName),
subtitle: CardType(ttText: contact.phones.elementAt(0).value),
leading: (contact.avatar != null && contact.avatar.length > 0)
? CircleAvatar(
backgroundImage: MemoryImage(contact.avatar),
)
: CircleAvatar(
child: Text(contact.initials()),
),
trailing: (contacts[index].isSelected)
? Icon(Icons.check)
: Icon(Icons.add),
);
},
),
);
}
Container searchBar(BuildContext context) {
return Container(
padding: EdgeInsets.all(15.0),
child: TextField(
controller: searchController,
decoration: InputDecoration(
labelText: 'Search',
border: new OutlineInputBorder(
borderSide: new BorderSide(
color: Theme.of(context).primaryColor,
),
),
prefixIcon: Icon(
Icons.search,
color: Colors.teal.shade300,
)),
),
);
}
}
当我调试代码时,我发现由于此行而发生错误
subtitle: CardType(ttText: contact.phones.elementAt(0).value)
在此方法中,contactListView(bool isSearching)
CardType()只是文本小部件
答案 0 :(得分:1)
添加空处理程序检查器;为:
CardType(ttText: contact.phones?contact.phones.elementAt(0).value:'')
试图运行您的代码,但遇到了一些问题。因此,我无法告诉您“ waitContact()”出了什么问题,但是您可以使用FutureBuilder。像下面这样的东西应该可以工作:
return Scaffold(
appBar: AppBar(
title: Text("Enable Notifications"),
),
body: FutureBuilder<bool>(
future: waitContact(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// YOUR CUSTOM CODE GOES HERE
return Column(
children: <Widget>[
AppbarCustom(
tMain: private_call,
),
Expanded(
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
searchBar(context),
contactListView(isSearching),
]),
),
),
],
);
} else {
return new CircularProgressIndicator();
}
}
)
);