当我回来或完成时如何重置我的控制器?

如何解决当我回来或完成时如何重置我的控制器?

enter image description here

我有一个 QuestionController 类 extends GetxController

当我使用控件退出页面时,我希望它停止工作(因为它仍在后台运行)并在我返回该页面时重新启动。

我已经尝试过:我在 ScoreScreen() 的路线之后添加了这些(在 nextQuestion () 中):

_isAnswered = false;
_questionNumber.value = 1; 

我在进入分数页面之前重置了数值。如果您转到分数页面,它可能会起作用,但是如果您早点回来,则不会。 (问题 num/4 在这里不起作用)。所以这种方式不适合。

当页面退出时,我可以通过什么方式停止并重置它?

控制器类代码:

class QuestionController extends GetxController
    with SingleGetTickerProviderMixin {
  PageController _pageController;

  PageController get pageController => this._pageController;

  List<Question> _questions = questions_data
      .map(
        (e) => Question(
            id: e["id"],question: e["question"],options: e["options"],answer: e["answer_index"]),)
      .toList();

  List<Question> get questions => this._questions;

  bool _isAnswered = false;

  bool get isAnswered => this._isAnswered;

  int _correctAns;

  int get correctAns => this._correctAns;

  int _selectedAns;

  int get selectedAns => this._selectedAns;

  RxInt _questionNumber = 1.obs;

  RxInt get questionNumber => this._questionNumber;

  int _numOfCorrectAns = 0;

  int get numOfCorrectAns => this._numOfCorrectAns;

  @override
  void onInit() {
    _pageController = PageController();
    super.onInit();
  }

  @override
  void onClose() {
    super.onClose();
    _pageController.dispose();
  }

  void checkAns(Question question,int selectedIndex) {
    _isAnswered = true;
    _correctAns = question.answer;
    _selectedAns = selectedIndex;

    if (_correctAns == _selectedAns) _numOfCorrectAns++;

    update();

    Future.delayed(Duration(seconds: 2),() {
      nextQuestion();
    });
  }

  void nextQuestion() {
    if (_questionNumber.value != _questions.length) {
      _isAnswered = false;
      _pageController.nextPage(
          duration: Duration(milliseconds: 300),curve: Curves.ease);
    } else {
      Get.off(ScoreScreen(correctNum: _numOfCorrectAns)); // GetMaterialApp()

      // _isAnswered = false;

      _numOfCorrectAns = 0;

      //_questionNumber.value = 1;

    }
  }

  void updateTheQuestionNum(int index) {
    _questionNumber.value = index + 1;
  }
}

完整代码如下

import 'package:flutter/material.dart';
import 'dart:async';
import 'package:get/get.dart';  // get: ^3.25.4

//  QuizPage()     ===============> 50. line      (Question 1/4) 81. line
//  QuestionCard()  ==============> 116. line
//  Option()   ===================> 163. line
//  QuestionController()  ========> 218. line
//  ScoreScreen() ================> 345. line

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      debugShowCheckedModeBanner: false,theme: ThemeData(canvasColor: Colors.blue),home: HomeScreen(),);
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Home Page"),),body: Center(
        child: InkWell(
          onTap: () {
            Navigator.push(
                context,MaterialPageRoute(builder: (context) => QuizPage()));
          },child: Container(
            padding: EdgeInsets.all(22),color: Colors.green,child: Text(
              "Go Quiz Page",style: TextStyle(color: Colors.white),);
  }
}

class QuizPage extends StatelessWidget {
  const QuizPage({
    Key key,}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    QuestionController _questionController = Get.put(QuestionController());

    return Scaffold(
      appBar: AppBar(
        title: Text("Quiz Page"),body: Stack(
        children: [
          SafeArea(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,children: [
                SizedBox(
                  height: 16,Padding(
                  padding: EdgeInsets.symmetric(horizontal: 16),child: Obx(
                    () => Center(
                      child: RichText(
                          text: TextSpan(
                              // text,style default adjust here OR:children[TextSpan(1,adjust 1),TextSpan(2,adjust 2),..]
                              text:
                                  "Question ${_questionController._questionNumber.value}",style: TextStyle(
                                  fontSize: 33,color: Colors.white70),children: [
                            TextSpan(
                                text:
                                    "/${_questionController._questions.length}",style: TextStyle(fontSize: 25))
                          ])),Divider(color: Colors.white70,thickness: 1),SizedBox(
                  height: 16,Expanded(
                  child: PageView.builder(
                    physics: NeverScrollableScrollPhysics(),controller: _questionController._pageController,onPageChanged: _questionController.updateTheQuestionNum,itemCount: _questionController.questions.length,itemBuilder: (context,index) => QuestionCard(
                      question: _questionController.questions[index],)
              ],)
        ],);
  }
}

class QuestionCard extends StatelessWidget {
  final Question question;

  const QuestionCard({
    Key key,@required this.question,}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    QuestionController _controller = Get.put(QuestionController());

    return Container(
      margin: EdgeInsets.only(left: 16,right: 16,bottom: 16),padding: EdgeInsets.all(16),decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(25),color: Colors.white,child: Column(
        children: [
          Text(
            question.question,style: TextStyle(fontSize: 22),SizedBox(
            height: 8,Flexible(
            child: SingleChildScrollView(
              child: Column(
                children: [
                  ...List.generate(
                      question.options.length,(index) => Option(
                          text: question.options[index],index: index,press: () => _controller.checkAns(question,index)))
                ],);
  }
}

class Option extends StatelessWidget {
  final String text;
  final int index;
  final VoidCallback press;

  const Option({
    Key key,@required this.text,@required this.index,@required this.press,}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GetBuilder<QuestionController>(
        init: QuestionController(),builder: (q) {
          Color getRightColor() {
            if (q.isAnswered) {
              if (index == q._correctAns) {
                return Colors.green;
              } else if (index == q.selectedAns &&
                  q.selectedAns != q.correctAns) {
                return Colors.red;
              }
            }
            return Colors.blue;
          }

          return InkWell(
            onTap: press,child: Container(
              //-- Option
              margin: EdgeInsets.only(top: 16),decoration: BoxDecoration(
                  color: getRightColor(),borderRadius: BorderRadius.circular(16)),child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,children: [
                  Text(
                    "${index + 1}. $text",style: TextStyle(fontSize: 16,color: Colors.white),],);
        });
  }
}

class QuestionController extends GetxController
    with SingleGetTickerProviderMixin {
  PageController _pageController;

  PageController get pageController => this._pageController;

  List<Question> _questions = questions_data
      .map(
        (e) => Question(
            id: e["id"],)
      .toList();

  List<Question> get questions => this._questions;

  bool _isAnswered = false;

  bool get isAnswered => this._isAnswered;

  int _correctAns;

  int get correctAns => this._correctAns;

  int _selectedAns;

  int get selectedAns => this._selectedAns;

  RxInt _questionNumber = 1.obs;

  RxInt get questionNumber => this._questionNumber;

  int _numOfCorrectAns = 0;

  int get numOfCorrectAns => this._numOfCorrectAns;

  @override
  void onInit() {
    _pageController = PageController();
    //_pageController.addListener(() { _questionNumber.value = _pageController.page.round()+1; });
    super.onInit();
  }

  @override
  void onClose() {
    super.onClose();
    _pageController.dispose();
  }

  void checkAns(Question question,curve: Curves.ease);
    } else {
      Get.off(ScoreScreen(correctNum: _numOfCorrectAns)); // GetMaterialApp()

      // _isAnswered = false;

      _numOfCorrectAns = 0;

      //_questionNumber.value = 1;

    }
  }

  void updateTheQuestionNum(int index) {
    _questionNumber.value = index + 1;
  }
}

class Question {
  final int id,answer;
  final String question;
  final List<String> options;

  Question({
    @required this.id,@required this.options,@required this.answer,});
}

const List questions_data = [
  {
    "id": 1,"question": "Question 1","options": ['option A','B','C','D'],"answer_index": 3,},{
    "id": 2,"question": "Question 2","answer_index": 2,{
    "id": 3,"question": "Question 3","answer_index": 0,{
    "id": 4,"question": "Question 4",];

class ScoreScreen extends StatelessWidget {
  final int correctNum;

  ScoreScreen({@required this.correctNum});

  @override
  Widget build(BuildContext context) {
    QuestionController _qController = Get.put(QuestionController());

    return Scaffold(
      body: Stack(
        fit: StackFit.expand,children: [
          Column(
            children: [
              Spacer(
                flex: 2,Text(
                "Score",style: TextStyle(fontSize: 55,Spacer(),Text(
                "${correctNum * 10}/${_qController.questions.length * 10}",style: TextStyle(fontSize: 33,Spacer(
                flex: 2,InkWell(
                onTap: () => Get.back(),borderRadius: BorderRadius.circular(16),child: Container(
                  padding: EdgeInsets.all(16),decoration: BoxDecoration(
                      borderRadius: BorderRadius.circular(16),color: Colors.white24),child: Text(
                    "Back to Home Page",);
  }
}

解决方法

更新答案:

好的,在看到您的完整代码后,我的解决方案需要几个额外的步骤。

将此添加到您的控制器类。它需要在您的 HomeScreen

的 onPressed 中调用
 void resetQuestionNumber() => _questionNumber.value = 1;

您必须提前初始化控制器,以便将其添加到您的 HomeScreen

final _questionController = Get.put(QuestionController());

您的 onTapHomeScreen 现在看起来像这样。

onTap: () {
    _questionController.resetQuestionNumber();
    Navigator.push(
    context,MaterialPageRoute(builder: (context) => QuizPage()));
},

应该可以。 _pageController 索引直到问题得到回答后才会更新,因此只需在转到 _questionNumber 之前重置 QuizPage,然后它就会赶上。您的 updateTheQuestionNum 可以完全消失,您无需再在 onPageChangedPageView.builder 中处理任何此类事情。

原答案:

如果您只是想让 RxInt _questionNumber_pageController 的值相匹配,您可以在 onInit 中添加一个监听器

_pageController.addListener(() {
  _questionNumber.value = _pageController.page.round() + 1;
});

编辑:添加 + 1 以说明从 0 开始的索引

,

你可以监听“onBack 事件”并配置控制器 这是一个例子

@override
Widget build(BuildContext context) {
  return WillPopScope(
    onWillPop: () {
      disposeController(context);
    },child: Scaffold(
      key: _scaffoldKey,appBar: AppBar(
        leading: IconButton(
            icon: Icon(Icons.arrow_back),onPressed: () {
              _moveToSignInScreen(context);
            }),title: Text("Profile"),),);

}

void disposeController(BuildContext context){
//or what you wnat to dispose/clear
 _pageController.dispose()
}
,

如果你只有一个控制器,你可以使用 Get.reset()。它会清除所有注册的实例。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-