我想用Flutter构建一个数学应用程序。它应该具有基本功能。然而,我面临以下问题:当我的计时器超时并且我被引导到下一页时,出现以下错误消息:
在完成小部件树时抛出了以下Assert:查找已停用小部件的祖先是不安全的。
此时,小部件的元素树的状态不再稳定。
要在小部件的dispose()方法中安全地引用其祖先,请通过在小部件的didChangeDependencies()方法中调用dependOnInheritedWidgetOfExactType()来保存对祖先的引用。
class MathFunctionScreen extends StatefulWidget {
static String id = "MathFunctionScreen";
const MathFunctionScreen({Key? key}) : super(key: key);
@override
State<MathFunctionScreen> createState() => _MathFunctionScreenState();
}
class _MathFunctionScreenState extends State<MathFunctionScreen>
with TickerProviderStateMixin {
DataBase db = DataBase();
late int myTime;
late int timeStamp;
@override
void initState() {
print("initState() wurde ausgeführt");
Provider.of<NumberGenerator>(context, listen: false).ctrl;
myOnChange();
Provider.of<NumberGenerator>(context, listen: false).mathCorrectAnswer;
Provider.of<NumberGenerator>(context, listen: false).operator;
Provider.of<NumberGenerator>(context, listen: false).setDatabase();
Provider.of<TimerProvider>(context, listen: false).startTimer(context);
animationController;
offsetAnimation;
animationController.forward();
super.initState();
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
}
@override
void dispose() {
Provider.of<TimerProvider>(context, listen: false).timer.cancel();
Provider.of<NumberGenerator>(context, listen: false)
.ctrl
.removeListener(() {});
animationController.dispose();
super.dispose();
}
late AnimationController animationController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 600),
);
late Animation<Offset> offsetAnimation =
Tween<Offset>(begin: const Offset(-3, 0), end: Offset.zero).animate(
CurvedAnimation(parent: animationController, curve: Curves.easeIn),
);
void myOnChange() {
Provider.of<NumberGenerator>(context, listen: false)
.textFieldTextChange(animationController);
}
void _updateText(String text) async {
String answer = (await Provider.of<NumberGenerator>(context, listen: false)
.mathCorrectAnswer)
.toString();
int answerLength = answer.length;
setState(() {
if (Provider.of<NumberGenerator>(context, listen: false)
.ctrl
.text
.length <
answerLength) {
Provider.of<NumberGenerator>(context, listen: false).ctrl.text =
Provider.of<NumberGenerator>(context, listen: false).ctrl.text +
text;
}
});
}
@override
Widget build(BuildContext context) {
double height = MediaQuery.of(context).size.height;
double width = MediaQuery.of(context).size.width;
下面的方法位于一个名为NumberGenerator的类中,该类继承了ChangeNotifier
void textFieldTextChange(AnimationController animationController) {
ctrl.addListener(
() async {
String mathCorrectAnswerString = (await mathCorrectAnswer).toString();
// user hat die zulässige Länge erreicht
if (ctrl.text.length >= mathCorrectAnswerString.length) {
//this delayed ist, damit die letzte zahl noch gesehen werden kann!
await Future.delayed(const Duration(milliseconds: 200));
checkAnswer(ctrl.text == mathCorrectAnswerString);
if (ctrl.text == mathCorrectAnswerString) {
updateDatabaseResult();
await Future.delayed(const Duration(milliseconds: 20));
wrongAnswers.clear();
wrongAnswers.add(addRightIcon);
notifyListeners();
await Future.delayed(const Duration(milliseconds: 500));
wrongAnswers.clear();
updateLeftAndRightInt();
setDatabase();
animationController.reset();
animationController.forward();
notifyListeners();
} else if (ctrl.text != mathCorrectAnswerString &&
(wrongAnswers.length <= 1)) {
updateDatabaseResult();
wrongAnswers.add(addWrongIcon);
notifyListeners();
await Future.delayed(const Duration(milliseconds: 500));
ctrl.clear();
} else {
updateDatabaseResult();
wrongAnswers.add(addWrongIcon);
notifyListeners();
await Future.delayed(const Duration(seconds: 1));
updateLeftAndRightInt();
setDatabase();
animationController.reset();
animationController.forward();
wrongAnswers.clear();
notifyListeners();
}
}
下面的类包含计时器。当它过期时,我被重定向到新页面并收到错误消息:
class TimerProvider extends ChangeNotifier {
late Timer timer;
late int value;
String collectionTime = "Time";
String key = "myTime";
startTimer(BuildContext context) {
timer = Timer.periodic(
const Duration(seconds: 1),
(timer) async {
if (value > 0) {
value--;
notifyListeners();
} else if (value <= 0) {
final QuerySnapshot<Map<String, dynamic>> documents =
await FirebaseFirestore.instance
.collection('Funktionen')
.where('result', isEqualTo: "")
.get();
final List<Future<void>> deleteFutures = [];
for (final QueryDocumentSnapshot<Map<String, dynamic>> document
in documents.docs) {
deleteFutures.add(document.reference.delete());
}
await Future.wait(deleteFutures);
timer.cancel();
if (context.mounted) {
Navigator.pushReplacementNamed(context, UserResultScreen.id);
// Navigator.pushNamed(context, UserResultScreen.id);
}
}
},
);
}
有人能帮我吗?
1条答案
按热度按时间v8wbuo2f1#
这是因为你在dispose of中调用了继承的widget,在你的示例中,这是Provider.of〈“Type”〉
你需要这样做: