V/FA (28362): Inactivity, disconnecting from the service
════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following assertion was thrown building:
A non-null String must be provided to a Text widget.
'package:flutter/src/widgets/text.dart':
Failed assertion: line 298 pos 10: 'data != null'
i used to codes and settings:
-----> contacts_service: ^0.3.10
`import 'dart:math';
import 'package:contacts_service/contacts_service.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@OverRide
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Contacts'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@OverRide
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
List contacts = [];
List contactsFiltered = [];
Map<String, Color> contactsColorMap = new Map();
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] == "+" ? "+" : "";
});
}
getAllContacts() async {
List colors = [
Colors.green,
Colors.indigo,
Colors.yellow,
Colors.orange
];
int colorIndex = 0;
List _contacts = (await ContactsService.getContacts()).toList();
_contacts.forEach((contact) {
Color baseColor = colors[colorIndex];
contactsColorMap[contact.displayName] = baseColor;
colorIndex++;
if (colorIndex == colors.length) {
colorIndex = 0;
}
});
setState(() {
contacts = _contacts;
});
}
filterContacts() {
List _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;
});
setState(() {
contactsFiltered = _contacts;
});
}
}
@OverRide
Widget build(BuildContext context) {
bool isSearching = searchController.text.isNotEmpty;
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container(
padding: EdgeInsets.all(20),
child: Column(
children: [
Container(
child: TextField(
controller: searchController,
decoration: InputDecoration(
labelText: 'Search',
border: new 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];
var baseColor = contactsColorMap[contact.displayName] as dynamic;
Color color1 = baseColor[800];
Color color2 = baseColor[400];
return ListTile(
title: Text(contact.displayName),
subtitle: Text(
contact.phones.elementAt(0).value
),
leading: (contact.avatar != null && contact.avatar.length > 0) ?
CircleAvatar(
backgroundImage: MemoryImage(contact.avatar),
) :
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
colors: [
color1,
color2,
],
begin: Alignment.bottomLeft,
end: Alignment.topRight
)
),
child: CircleAvatar(
child: Text(
contact.initials(),
style: TextStyle(
color: Colors.white
)
),
backgroundColor: Colors.transparent
)
)
);
},
),
)
],
),
),
);
}
}`