首页 > 解决方案 > Flutter setState() 函数被调用但没有做任何事情

问题描述

设法创建了一个我在真实程序中遇到的错误的简单再现,我不确定为什么会发生这种事情。我想如果我能理解这一点,它可能会对我有所帮助。

这里的关键是我必须以这种方式将程序的两个部分分开,并且它们需要进行通信,但是这种通信并没有按照我期望的方式进行。(所以请不要建议我将定时器功能放在程序的其余部分中)。

import 'package:flutter/material.dart';
import 'dart:async';

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(

        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool textBool = false;

  void textChanger() {
    if (textBool) {
    setState(() {
      textBool = false;
    });
    } else {
      setState(() {
        textBool = true;
      });
    }
  }

  Text myText() {
    if (textBool) {
      Text newText = new Text('Original Text');
      return newText;
    } else {
      Text newText = new Text('New Text');
      return newText;
    }
  }


  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(

        title: Text(widget.title),
      ),
      body: Center(
        child: myText(),          
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: stateModify,
        tooltip: 'Change Text',
      ), 
    );
  }
}

Future<void> stateModify() {

  Duration waitTimer = new Duration(seconds: 5);
  new Timer.periodic(waitTimer, (timer) {
    _MyHomePageState().textChanger();
    timer.cancel();
  });

}

预期功能:单击按钮,5 秒后它应该会更改为第二组文本。然后我应该能够再次单击该按钮并将其切换回来。

相反,在此示例中,我收到以下错误:

[VERBOSE-2:ui_dart_state.cc(157)] 未处理的异常:setState() 在构造函数中调用:_MyHomePageState#a5177(生命周期状态:已创建,无小部件,未安装)

谷歌似乎在这个特定问题上并没有太大帮助。

有什么建议么?

标签: iosfunctionscope

解决方案


您的stateModify函数不是_MyHomePageState. 此外,当您访问_MyHomePageState().textChanger()in时,stateModify您最终会创建一个新对象,_MyHomePageState()但不会插入渲染树。

您应该使用Timer而不是Timer.periodic. 将Timer.periodic重复该任务,直到Timer.cancel被调用。Timer将在您需要的给定时间段后进行回调。

textChanger在调用时传递函数stateModify,这样你就可以在_MyHomePageState不创建新对象的情况下调用函数。

进行以下更改。

floatingActionButton: FloatingActionButton(
        onPressed: ()=> stateModify(textChanger),
        tooltip: 'Change Text',
),

stateModify(dynamic function) {
   Timer(Duration(seconds: 5), function);
}

推荐阅读