我已经建立了一个卡片,它将打开一个searchDelegate,用户可以在其中搜索汽车。选择汽车时,代表屏幕将关闭onTap: () {close(context, carList[index].id);}
。然后,ID将在主屏幕上更新并添加到列表中。
但是,我一直有错误setState() called after dispose()
List<String> selectedCar = [];
// Function to open SearchDelegate
void openCarSearchDelegate() async {
String? selectedCarId = await showSearch(
context: context,
delegate: CompareCarSearchDelegate(_firebaseServices.carsRef),
);
print(selectedCarId) // <- Returns value when car is selected
if (selectedCarId != null) {
addSelectedCar(selectedCarId);
}
}
// Update the state to add to the List
void addSelectedCar(String carId) {
// ERROR occurs here
setState(() {
selectedCar.add(carId);
});
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(20),
child: SelectCarCard(
onTap: openCarSearchDelegate,
),
);
}
class SelectCarCard extends StatelessWidget {
const SelectCarCard({
Key? key,
required this.onTap,
}) : super(key: key);
final void Function() onTap;
@override
Widget build(BuildContext context) {
return InkWell(
borderRadius: const BorderRadius.all(Radius.circular(12)),
onTap: onTap,
child: Ink(
height: 200,
width: double.infinity,
child: SizedBox(
height: 200,
width: double.infinity,
child: const Text(
"Select Car",
style: TextStyle(
color: Colors.black,
fontSize: 18,
),
),
),
),
);
}
}
class CompareCarSearchDelegate extends SearchDelegate<String> {
final Query searchQuery;
CompareCarSearchDelegate(this.searchQuery);
@override
String get searchFieldLabel => 'Select car...';
@override
TextStyle get searchFieldStyle => const TextStyle(fontSize: 18);
@override
List<Widget> buildActions(BuildContext context) {
// Clear field
}
@override
Widget buildLeading(BuildContext context) {
// Return to previous screen
}
@override
Widget buildResults(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: searchQuery.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator(
backgroundColor: Colors.white,
color: kPrimaryColor,
strokeWidth: 3,
);
}
List<DocumentSnapshot> documents = snapshot.data!.docs;
final carList = documents.where((doc) {
// Get results based on search text
}).toList();
return ListView.separated(
separatorBuilder: (context, index) {
return const Divider();
},
shrinkWrap: true,
padding:
const EdgeInsets.only(top: 20, bottom: 20, left: 10, right: 10),
itemCount: carList.length,
itemBuilder: (context, index) {
return ListTile(
contentPadding: const EdgeInsets.only(right: 10),
title: Text(
carList[index]['name'],
overflow: TextOverflow.ellipsis,
),
onTap: () {
close(context, carList[index].id);
},
);
},
);
},
);
}
@override
Widget buildSuggestions(BuildContext context) {
return Container();
}
}
I/flutter (28352): setState() called after dispose(): _BodyState#27420(lifecycle state: defunct, not mounted)
I/flutter (28352): This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer includes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback.
I/flutter (28352): The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" property of this object before calling setState() to ensure the object is still in the tree.
I/flutter (28352): This error might indicate a memory leak if setState() is being called because another object is retaining a reference to this State object after it has been removed from the tree. To avoid memory leaks, consider breaking the reference to this object during dispose().
我尝试添加if(mounted) {setState(() {selectedCar.add(carId);});}
,但mounted
一直返回false。
任何想法,我如何可以实现它或任何解决方案将不胜感激。谢谢
3条答案
按热度按时间nlejzf6q1#
试试这个
4zcjmb1e2#
你的
close(context, carList[index].id);
函数是异步的吗?如果是,则替换onTap: () { close(context, carList[index].id)},
与
onTap: () async {await close(context, carList[index].id)},
。如果不是,那么你的错误表明有一些异步调用负责调用
setState()
不同的上下文也可能是一个问题。
和/或
编辑:
尝试在此区域安装。
或者因为
StreamBuilder<QuerySnapshot>
,你的代码仍然处于aync状态,(可能这就是它从不显示mount的原因)。尝试用以下内容替换上面的内容。(如果上面的内容不起作用)d8tt03nd3#
一个简单的测试代码与类似的情况