ayc*_*cha 6 navigation flutter flutter-dependencies flutter-state
我想用 Flutter 构建一个数学应用程序。应该有基本的功能。但是,我面临以下问题:当我的计时器耗尽并且我被定向到下一页时,会出现以下错误消息:
\n完成小部件树时抛出以下断言:\n查找已停用小部件的祖先是不安全的。
\n此时小部件的元素树的状态不再稳定。
\n要在 widget 的 dispose() 方法中安全地引用它的祖先,请通过在 widget 的 didChangeDependency() 方法中调用 dependentOnInheritedWidgetOfExactType() 来保存对祖先的引用。
\nclass MathFunctionScreen extends StatefulWidget {\n static String id = "MathFunctionScreen";\n const MathFunctionScreen({Key? key}) : super(key: key);\n @override\n State<MathFunctionScreen> createState() => _MathFunctionScreenState();\n}\n\nclass _MathFunctionScreenState extends State<MathFunctionScreen>\n with TickerProviderStateMixin {\n DataBase db = DataBase();\n late int myTime;\n late int timeStamp;\n @override\n void initState() {\n print("initState() wurde ausgef\xc3\xbchrt");\n Provider.of<NumberGenerator>(context, listen: false).ctrl;\n myOnChange();\n Provider.of<NumberGenerator>(context, listen: false).mathCorrectAnswer;\n Provider.of<NumberGenerator>(context, listen: false).operator;\n Provider.of<NumberGenerator>(context, listen: false).setDatabase();\n Provider.of<TimerProvider>(context, listen: false).startTimer(context);\n animationController;\n offsetAnimation;\n animationController.forward();\n super.initState();\n }\n\n @override\n void didChangeDependencies() {\n super.didChangeDependencies();\n }\n\n @override\n void dispose() {\n Provider.of<TimerProvider>(context, listen: false).timer.cancel();\n Provider.of<NumberGenerator>(context, listen: false)\n .ctrl\n .removeListener(() {});\n animationController.dispose();\n super.dispose();\n }\n\n late AnimationController animationController = AnimationController(\n vsync: this,\n duration: const Duration(milliseconds: 600),\n );\n late Animation<Offset> offsetAnimation =\n Tween<Offset>(begin: const Offset(-3, 0), end: Offset.zero).animate(\n CurvedAnimation(parent: animationController, curve: Curves.easeIn),\n );\n void myOnChange() {\n Provider.of<NumberGenerator>(context, listen: false)\n .textFieldTextChange(animationController);\n }\n\n void _updateText(String text) async {\n String answer = (await Provider.of<NumberGenerator>(context, listen: false)\n .mathCorrectAnswer)\n .toString();\n int answerLength = answer.length;\n setState(() {\n if (Provider.of<NumberGenerator>(context, listen: false)\n .ctrl\n .text\n .length <\n answerLength) {\n Provider.of<NumberGenerator>(context, listen: false).ctrl.text =\n Provider.of<NumberGenerator>(context, listen: false).ctrl.text +\n text;\n }\n });\n }\n\n @override\n Widget build(BuildContext context) {\n double height = MediaQuery.of(context).size.height;\n double width = MediaQuery.of(context).size.width;\nRun Code Online (Sandbox Code Playgroud)\n而下面的方法是在一个名为NumberGenerator的类中,该类继承了ChangeNotifier
\nvoid textFieldTextChange(AnimationController animationController) {\n ctrl.addListener(\n () async {\n String mathCorrectAnswerString = (await mathCorrectAnswer).toString();\n // user hat die zul\xc3\xa4ssige L\xc3\xa4nge erreicht\n if (ctrl.text.length >= mathCorrectAnswerString.length) {\n //this delayed ist, damit die letzte zahl noch gesehen werden kann!\n await Future.delayed(const Duration(milliseconds: 200));\n checkAnswer(ctrl.text == mathCorrectAnswerString);\n if (ctrl.text == mathCorrectAnswerString) {\n updateDatabaseResult();\n await Future.delayed(const Duration(milliseconds: 20));\n wrongAnswers.clear();\n wrongAnswers.add(addRightIcon);\n notifyListeners();\n await Future.delayed(const Duration(milliseconds: 500));\n wrongAnswers.clear();\n updateLeftAndRightInt();\n setDatabase();\n animationController.reset();\n animationController.forward();\n notifyListeners();\n } else if (ctrl.text != mathCorrectAnswerString &&\n (wrongAnswers.length <= 1)) {\n updateDatabaseResult();\n wrongAnswers.add(addWrongIcon);\n notifyListeners();\n await Future.delayed(const Duration(milliseconds: 500));\n ctrl.clear();\n } else {\n updateDatabaseResult();\n wrongAnswers.add(addWrongIcon);\n notifyListeners();\n await Future.delayed(const Duration(seconds: 1));\n updateLeftAndRightInt();\n setDatabase();\n animationController.reset();\n animationController.forward();\n wrongAnswers.clear();\n notifyListeners();\n }\n }\nRun Code Online (Sandbox Code Playgroud)\n下面的类包含计时器。当它过期时,我被重定向到新页面并收到错误消息:
\nclass TimerProvider extends ChangeNotifier {\n late Timer timer;\n late int value;\n String collectionTime = "Time";\n String key = "myTime";\n startTimer(BuildContext context) {\n timer = Timer.periodic(\n const Duration(seconds: 1),\n (timer) async {\n if (value > 0) {\n value--;\n notifyListeners();\n } else if (value <= 0) {\n final QuerySnapshot<Map<String, dynamic>> documents =\n await FirebaseFirestore.instance\n .collection('Funktionen')\n .where('result', isEqualTo: "")\n .get();\n final List<Future<void>> deleteFutures = [];\n for (final QueryDocumentSnapshot<Map<String, dynamic>> document\n in documents.docs) {\n deleteFutures.add(document.reference.delete());\n }\n await Future.wait(deleteFutures);\n timer.cancel();\n if (context.mounted) {\n Navigator.pushReplacementNamed(context, UserResultScreen.id);\n // Navigator.pushNamed(context, UserResultScreen.id);\n }\n }\n },\n );\n }\nRun Code Online (Sandbox Code Playgroud)\n有人可以帮我弄这个吗 ?
\n小智 8
这是因为您在 dispose of 中调用了继承的小部件,在您的示例中这是 Provider.of<"Type">
你需要这样做:
class _MathFunctionScreenState extends State<MathFunctionScreen>
with TickerProviderStateMixin {
...
NumberGenerator numberGenerator;
TimerProvider timerProvider;
...
@override
void didChangeDependencies() {
numberGenerator = Provider.of<NumberGenerator>;
timerProvider = Provider.of<TimerProvider>;
super.didChangeDependencies();
}
@override
void dispose() {
timerProvider.timer.cancel();
numberGenerator.ctrl.removeListener(() {});
animationController.dispose();
super.dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10565 次 |
| 最近记录: |