flutter - setState()在抖动中无法正常工作

标签 flutter dart

我在闪屏中有一个问题选项板,用户在其中轻点显示该问题的问题编号,并单击下一步按钮以显示下一个问题。
如果我使用问题选项板在问题之间遍历,则可以正常工作,但是当我单击“下一步”按钮时,它不会将选项板上的问题号变为绿色(我希望该问题号变为绿色),并且也不会返回下一个问题,但循环迭代。当我按下按钮一段时间后,它表示没有其他问题,因为在循环结束时我已设置了此消息。
这是我的代码:

class quizpage extends StatefulWidget{

  var questions,surveyid;

  quizpage(this.questions,this.surveyid);

  //quizpage({Key key, @required this.questions}) : super(key : key);

  @override
  _quizpageState createState() => _quizpageState(questions,surveyid);
}

class _quizpageState extends State<quizpage> with SingleTickerProviderStateMixin {

  var questions,surveyid;




  _quizpageState(this.questions,this.surveyid);

  int i = 0;

  int flag = 0;
  int counter = 0;
  int length;



  Map<String, Color> btncolor = {
    "1" : Colors.grey,
    "2" : Colors.grey,
    "3" : Colors.grey,
    "4" : Colors.grey,
    "5" : Colors.grey,
    "6" : Colors.grey,
    "7" : Colors.grey,
    "8" : Colors.grey,
    "9" : Colors.grey,
  };



  final answercontroller = TextEditingController();



  @override
  Widget build(BuildContext context) {
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitDown, DeviceOrientation.portraitUp
    ]);
    SizeConfig().init(context);
    // TODO: implement build
    return Scaffold(
        body: SingleChildScrollView(
          scrollDirection: Axis.vertical,
          child: SizedBox(
            height: 600,
            child: Column(
              children: <Widget>[
                Expanded(
                  flex: 1,
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: <Widget>[
                      Numberofquestion()
                    ],
                  ),
                ),
                Expanded(
                    flex: 4,
                    child: Center(
                      child: Container(
                        width: 400,
                        height: 400,
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                          children: <Widget>[
                            Container(
                              width: 250,
                              child: Material(
                                elevation: 5,
                                color: Colors.deepOrange,
                                borderRadius: BorderRadius.all(
                                    Radius.circular(10.0)),
                                child: TextField(
                                  enabled: false,
                                  maxLines: 6,
                                  decoration: InputDecoration(
                                      fillColor: Colors.white,
                                      filled: true,
                                      hintText: questions[i]
                                  ),
                                  style: TextStyle(
                                      fontSize: 20,
                                      color: Colors.black
                                  ),
                                ),
                              ),
                            )
                          ],
                        ),
                      ),
                    )
                ),
                Expanded(
                    flex: 2,
                    child: Center(
                        child: Container(
                            width: 300,
                            height: 300,
                            child: Column(
                                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                                children: <Widget>[
                                  Container(
                                    width: 250,
                                    child: Material(
                                      elevation: 2,
                                      color: Colors.deepOrange,
                                      borderRadius: BorderRadius.all(
                                          Radius.circular(10.0)),
                                      child: TextField(
                                        controller: answercontroller,
                                        maxLines: 1,
                                        //enabled: false,
                                        decoration: InputDecoration(
                                            fillColor: Colors.white,
                                            filled: true,
                                            hintText: 'Answer'
                                        ),
                                        style: TextStyle(
                                            fontSize: 20,
                                            color: Colors.black
                                        ),
                                      ),
                                    ),
                                  ),
                                ]
                            )
                        )
                    )
                ),
                Expanded(
                    flex: 2,
                    child: Align(
                      alignment: Alignment.topCenter,
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                            children: <Widget>[
                              RaisedButton(onPressed: SkipQuestion,
                                color: Colors.deepOrange,
                                textColor: Colors.white,
                                shape: RoundedRectangleBorder(
                                    borderRadius: BorderRadius.all(
                                        Radius.circular(10.0))),
                                child: Text('Skip',
                                  style: TextStyle(
                                      fontSize: 20
                                  ),
                                ),
                              ),
                              RaisedButton(onPressed: NextQuestion,
                                color: Colors.green,
                                textColor: Colors.white,
                                shape: RoundedRectangleBorder(
                                    borderRadius: BorderRadius.all(
                                        Radius.circular(10.0))),
                                child: Text('Next',
                                  style: TextStyle(
                                      fontSize: 20
                                  ),
                                ),
                              ),
                            ],
                          ),
                        ],
                      ),
                    )
                )
              ],
            ),
          ),
        ),
      ),
    );
  }

  @override
  void setState(fn) {
    // TODO: implement setState
    super.setState(fn);
    if(btncolor[(i+1).toString()] == Colors.deepOrange){
      btncolor[(i+1).toString()] = Colors.purple;
      flag = 1;
    }
    else if(btncolor[(i+1).toString()] == Colors.green){
      btncolor[(i+1).toString()] = Colors.purple;
      flag = 2;
    }
    else{
      btncolor[(i+1).toString()] = Colors.purple;
    }
  }

  void NextQuestion() async {
    if(answercontroller.text.length == 0){
      await showDialog(
        context: context,
        builder: (context) => new AlertDialog(
          title: new Text('Alert'),
          content: Text(
              'Please enter an answer.'),
          actions: <Widget>[
            new FlatButton(
              onPressed: () {
                Navigator.of(context, rootNavigator: true)
                    .pop(); // dismisses only the dialog and returns nothing
              },
              child: new Text('OK'),
            ),
          ],
        ),
      );
    }
    else{
      setState(() async {
        if(i < (questions.length - 1)){
          // ignore: unnecessary_statements
          btncolor[(i+1).toString()] = Colors.green;
          i++;
        }
        else{
          await showDialog(
            context: context,
            builder: (context) => new AlertDialog(
              title: new Text('Alert'),
              content: Text(
                  'There are no next questions.'),
              actions: <Widget>[
                new FlatButton(
                  onPressed: () {
                    Navigator.of(context, rootNavigator: true)
                        .pop(); // dismisses only the dialog and returns nothing
                  },
                  child: new Text('OK'),
                ),
              ],
            ),
          );
        }
      });

    }

  }


  @override
  void initState() {
    SystemChrome.setEnabledSystemUIOverlays([]);
    super.initState();
  }





  void SkipQuestion() {
    setState(() {
      if(i < (questions.length - 1)){
        // ignore: unnecessary_statements
        btncolor[(i+1).toString()] = Colors.deepOrange;
        i++;
      }
      else{
        Navigator.of(context).pushReplacement(MaterialPageRoute(
          builder: (context) => resultpage(surveyid),
        ));
      }
    });
  }



  void ChooseQuestion() {
    setState(() {
      if(i < (questions.length)){
        for(int k =0; k< (questions.length); k++){
          if(k != i){
            if(btncolor[(k+1).toString()] == Colors.purple){
              if(flag == 1){
                btncolor[(k+1).toString()] = Colors.red;
                flag =0;
              }
              else if(flag == 2){
                btncolor[(k+1).toString()] = Colors.green;
                flag =0;
              }
              else{
                btncolor[(k+1).toString()] = Colors.grey;
              }

            }
          }
          else{
            if(btncolor[(k+1).toString()] == Colors.purple){
              if(flag == 1){
                btncolor[(k+1).toString()] = Colors.red;
              }
              else if(flag == 2){
                btncolor[(k+1).toString()] = Colors.green;
                flag =0;
              }
              else{
                btncolor[(k+1).toString()] = Colors.grey;
              }
            }
          }
        }
        //i++;
      }
      else{
        Navigator.of(context).pushReplacement(MaterialPageRoute(
          builder: (context) => resultpage(surveyid),
        ));
      }
    });
  }

  Widget Numberofquestion() {
    if(questions.length == 9){
      return Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          Container(
            width: 40,
            padding: EdgeInsets.all(5),
            child: RaisedButton(onPressed: () {
              i = 0;
              ChooseQuestion();
            },
              color: btncolor["1"],
              textColor: Colors.white,
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.all(
                      Radius.circular(10.0))),
              child: Text("1",
                textAlign: TextAlign.center,
                style: TextStyle(
                    fontSize: 20
                ),
              ),
            ),
          ),
          Container(
            width: 40,
            padding: EdgeInsets.all(5),
            child: RaisedButton(onPressed: () {
              i = 1;
              ChooseQuestion();
            },
              color: btncolor["2"],
              textColor: Colors.white,
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.all(
                      Radius.circular(10.0))),
              child: Text('2',
                textAlign: TextAlign.center,
                style: TextStyle(
                    fontSize: 20
                ),
              ),
            ),
          ),
          Container(
            width: 40,
            padding: EdgeInsets.all(5),
            child: RaisedButton(onPressed: () {
              i = 2;
              ChooseQuestion();
            },
              color: btncolor["3"],
              textColor: Colors.white,
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.all(
                      Radius.circular(10.0))),
              child: Text('3',
                textAlign: TextAlign.center,
                style: TextStyle(
                    fontSize: 20
                ),
              ),
            ),
          ),
          Container(
            width: 40,
            padding: EdgeInsets.all(5),
            child: RaisedButton(onPressed: () {
              i = 3;
              ChooseQuestion();
            },
              color: btncolor["4"],
              textColor: Colors.white,
              shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.all(
                      Radius.circular(10.0))),
              child: Text('4',
                textAlign: TextAlign.center,
                style: TextStyle(
                    fontSize: 20
                ),
              ),
            ),
          ),
        ],
      );
    }
  }
}
在这里,问题是存储问题的数组。
当我使用“跳过”按钮时,setState可以正常工作,但是当我使用“下一步”按钮时,setState无法工作。
有人可以帮我吗?

最佳答案

我会说你以错误的方式操纵国家
正如docs所指:

@protected
void setState (VoidCallback fn)

The provided callback is immediately called synchronously. It must not return a future (the callback cannot be async), since then it would be unclear when the state was actually being set.


注意事项:
  • 不要在 initState()内调用 setState()
  • 不要在 build()
  • 内的同步代码中调用 setState()
  • setState()应该同步运行,以便自动进行新更新
  • 因此,请尽量不要将 setState()标记为异步

  • 您可能会看到link,希望它有用

    关于flutter - setState()在抖动中无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64096409/

    相关文章:

    dart - Flutter:设置Painter类的背景图像

    dart - 在手势检测器中有多个 SetStates()?

    flutter - 关闭抽屉后重新聚焦 TextField

    flutter - 如何跨 Flutter 移动、网络和窗口添加条件导入?

    dart - 如何使用 Flutter 在 iOS 和 Android 上共享图像?

    flutter - 如何在 Flutter 中离线渲染 Latex

    dart - 容器不占用 BoxDecoration 图像的大小

    ios - 如何从 flutter -> swift && swift -> flutter 传递数据?

    flutter - 当我双击 flutter_console.bat 时,它在一秒钟内打开和关闭?

    flutter - flutter 如何从底部产生模态路线动画