flutter - 在flutter应用程序中递归调用3个函数而不减慢应用程序
问题描述
我在主小部件中调用了 3 个函数,因为该应用程序从 firebase 加载数据需要花费太多时间,而且整个应用程序都会挂起。有没有其他方法可以调用这 3 个函数并且也可以使用该功能。
import 'package:flutter/material.dart';
import 'package:rigato/global.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:rigato/ClientsDetail/ClientDetailTab.dart';
import 'package:rigato/localization/app_translations.dart';
class Clients1 extends StatefulWidget {
final searchText;
Clients1({this.searchText});
@override
State<StatefulWidget> createState() => _Clients();
}
class _Clients extends State<Clients1> {
ScrollController controller;
void initState() {
super.initState();
}
//Function for call
void _call(String number) async {
if (await canLaunch(number)) {
await launch(number);
} else {
throw 'Could not launch $number';
}
}
//Function for Email
void _sendEmail(String emailAddress) async {
if (await canLaunch(emailAddress)) {
await launch(emailAddress);
} else {
throw 'Could not launch $emailAddress';
}
}
// Function for make list according search data
List<DocumentSnapshot> initialData = List<DocumentSnapshot>();
getSearchText() {
List<DocumentSnapshot> tempList = List<DocumentSnapshot>();
for (int i = 0; i < initialData.length; i++) {
var name = initialData[i]["nameFs"] + initialData[i]["nameLs"];
var city = initialData[i]["city"] == null ? "" : initialData[i]["city"];
if (name.toLowerCase().contains(widget.searchText.toLowerCase()) ||
initialData[i]["idOrder"]
.toLowerCase()
.contains(widget.searchText.toLowerCase()) ||
city.toLowerCase().contains(widget.searchText.toLowerCase())) {
tempList.add(initialData[i]);
}
}
clientData = tempList;
setState(() {});
}
int sequenceIndex;
String sequenceName;
getStatus() async {
final prefs = await SharedPreferences.getInstance();
if (this.mounted) {
setState(() {
sequenceIndex = prefs.getInt("previousIndex");
});
}
QuerySnapshot snapshot =
await Firestore.instance.collection('sequence').getDocuments();
for (int i = 0; i < clientData.length; i++) {
if (sequenceIndex == snapshot.documents[i].data['index']) {
setState(() {
sequenceName = snapshot.documents[i].data['sequenceName'];
});
}
// print("this is sequence name ${sequenceName}");
}
}
var clientData;
bool isGet = false;
getData() async {
CollectionReference collectionReference =
Firestore.instance.collection('clients');
QuerySnapshot collectionSnapshot = await collectionReference.getDocuments();
clientData = collectionSnapshot.documents;
initialData = collectionSnapshot.documents;
// initialData = [];
for (int i = 0; i < clientData.length; i++) {
print("log of sequence name ${sequenceName}");
if (sequenceName == clientData[i]['sequenceStatus']) {
print("this is clientdata${clientData[i]['sequenceStatus']}");
initialData.add(clientData[i]);
}
}
print("this is initial data ${initialData}");
setState(() {
isGet = true;
});
}
@override
Widget build(BuildContext context) {
getSearchText();
getData();
getStatus();
if (clientData.isEmpty) {
clientData = initialData;
}
return isGet == false
? Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(appColor),
))
: Container(
color: offWhite,
child: Scrollbar(
child: ListView.builder(
controller: controller,
itemCount: clientData.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () async {
final prefs = await SharedPreferences.getInstance();
prefs.setString(
'clientId', clientData[index].documentID);
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) =>
ClientDetailTab(),
),
);
},
onLongPress: () {
AlertBox().show(
context,
AppTranslations.of(context).text("alert"),
AppTranslations.of(context)
.text("do-you-want-to-delete-this-record?"),
(value) {
Navigator.of(context).pop();
Firestore.instance
.collection('clients')
.document(
clientData[index].documentID,
)
.delete()
.catchError((e) {});
});
},
child: Container(
color: clientData[index]['sector'] == "all"
? yellow
: offWhite,
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Padding(
padding:
EdgeInsets.only(left: 10, right: 10),
child: IconButton(
icon:
Icon(Icons.star_border, color: grey),
onPressed: () {},
),
),
Expanded(
child: Container(
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
LightText(
text: clientData[index]['nameFs'] ==
null ||
clientData[index]['nameLs'] ==
null
? ""
: clientData[index]['nameFs'] +
" " +
clientData[index]['nameLs'],
),
LightText(
text: clientData[index]['idOrder']),
LightText(
text: clientData[index]['city'] ==
null
? ""
: clientData[index]['city']),
],
)),
),
Column(
children: <Widget>[
IconButton(
icon: Icon(
Icons.call,
color: grey,
),
onPressed: () {
String mob =
clientData[index]['mobileOne'];
_call('tel:$mob');
},
),
IconButton(
icon: Icon(Icons.email, color: grey),
onPressed: () {
String email =
clientData[index]['emailOne'];
_sendEmail('mailto:$email');
},
)
],
),
],
),
Padding(
padding: EdgeInsets.only(left: 70, top: 0),
child: Container(
decoration: BoxDecoration(
border: Border(
top: BorderSide(color: Colors.grey[400]),
),
),
),
),
],
)));
},
),
),
);
}
}
Widget build(BuildContext context) {
getSearchText();
getData();
getStatus();
}
这些是我递归调用以从 firebase 获取数据的 3 个函数。和搜索功能。
解决方案
为了防止应用程序冻结,您应该使用“计算”功能创建一个隔离,这将与主线程分开处理数据。示例 https://flutter.dev/docs/cookbook/networking/background-parsing
链接中提供的示例
Future<List<Photo>> fetchPhotos(http.Client client) async {
final response =
await client.get('https://jsonplaceholder.typicode.com/photos');
// Use the compute function to run parsePhotos in a separate isolate.
return compute(parsePhotos, response.body);
}