在 initState 上声明时 setState 不更新变量

setState not updating variable when declared on initState

我 运行 遇到了 Flutter 的问题:我有一个 navbar,根据所选的项目,returns 我有一个名为 Index 的整数。然后通过一个List传递这个index得到Scaffold的body内容,一个Widget()class.

的对象

默认正文是 HomePage() 的对象,它有一个名为 rpm 的整数参数。默认情况下,HomePage() 应该是显示的正文,因此,由于它取决于 rpm 参数,我在 initState 上声明了 rpm 参数。我还有一个 setState 动态改变 rpm.

奇怪的是:如果我在 initState 中声明 List<Widgets> bodyListsetState 似乎不起作用。但是,如果我在构建方法中声明 List<Widgets> bodyList,我可以看到 HomePage() 的内容随 rpm.

动态变化

代码摘录。不工作:

class _ScreenTreeState extends State<ScreenTree> {
  int _index;
  int _rpm;
  List<Widget> bodyList;

  @override
  void initState() {
    _isPlaying = false;
    _rpm = 0;
    _index = 0;
    bodyList = [
      HomePage(rpm: _rpm),
      StatisticsScreen(),
      WeightScreen(),
      SettingsPage()
    ];
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(...

工作:

class _ScreenTreeState extends State<ScreenTree> {
  int _index;
  int _rpm;
  List<Widget> bodyList;

  @override
  void initState() {
    _isPlaying = false;
    _rpm = 0;
    _index =
        0;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    bodyList = [
      HomePage(rpm: _rpm),
      StatisticsScreen(),
      WeightScreen(),
      SettingsPage()
    ];
    
    return Scaffold(...

我的理论是,这可能与以下事实有关:如果 _rpm 被声明为整数,Dart 会将其作为原始类型而不是整数 class 的对象来读取,所以如果在 initState 上声明,我实际上不是在传递一个对象,而是一个原语。但是我不明白为什么它在 build 方法中声明时有效。

我觉得这无关紧要,但如果有人需要,这里是更新_rpm值的代码。拜托,不要读太多,因为我觉得它实际上是不相关的,可能会分散注意力和混淆而不是帮助:

onPressed: () {
          if (_isPlaying) {
            setState(() {
              _isPlaying = false;
            });
            Provider.of<MicrophoneEngine>(context, listen: false)
                .stopRecording();
          } else {
            setState(() {
              _isPlaying = true;
            });
            Provider.of<MicrophoneEngine>(context, listen: false)
                .startRecording((rpmCall) {
              setState(() {
                _rpm = rpmCall;
              });
            });
          }
        },

保留小部件的引用是一种不好的做法(如第一个示例),事实上,您根本不需要该列表。

每次使用 setState 时,都会重建小部件并传递新值。在第一个示例中,您每次都从 init 传递 HomePage(rpm: _rpm),这就是它不更新的原因。意思是,您不使用更新后的值重建 HomePage,您只是从 initState 传递 HomePage,它是用 0 的初始 _rpm 值实例化的。