setState 不更新 wiget UI

setState does not update wiget UI

我花了几个小时试图理解为什么单击 IconButton 不会切换更改其图标。

import 'package:flutter/material.dart';
import 'dart:core';
class TestIconChange extends StatefulWidget {
  @override
  _TestIconChangeState createState() => _TestIconChangeState();
}

class _TestIconChangeState extends State<TestIconChange>
    with TickerProviderStateMixin {
  IconData _iconData = Icons.add;
  AnimationController _animationController1;

  Widget _child;

  @override
  void initState() {
    super.initState();
    _animationController1 = AnimationController(
      vsync: this,
      value: 1,
      duration: Duration(seconds: 1),
    );
  }

  @override
  Widget build(BuildContext context) {
    if (_child == null) _child = _buildButton();
    return Scaffold(
      body: Container(
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              AnimatedSwitcher(
                duration: Duration(milliseconds: 100),
                child: _child,
              ),
              RaisedButton(
                child: Text('Text Child'),
                onPressed: (() {
                  setState(() {
                    _child = Text('Dummy text');
                  });
                }),
              ),
              RaisedButton(
                child: Text('Button Child'),
                onPressed: (() {
                  setState(() {
                    _child =_buildButton();
                  },);
                }),
              )
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildButton() {
    return      IconButton(
      onPressed: () {
        setState(() {
          (_iconData == Icons.add)
              ? _iconData = Icons.remove
              : _iconData = Icons.add;
        });
      },
      icon: Icon(_iconData),
    );

  }
}

当您调用 setState 时,它只会重建在 build 方法中构建的小部件。

主要问题是你没有做。您没有在 build 方法中重建 _child

你代码中的这一行是错误的:if (_child == null) _child = _buildButton();

如果你这样做 _child = _buildButton(); 则只能使用按钮 +/-,但不能更改为文本。需要重构您的代码!

因此,我对您的代码进行了重构,并添加了 ChildType 以指示您要显示的 Widget 类型:文本或按钮。然后在 setState 方法中使用它。现在可以正常使用了,如您所料:)

import 'package:flutter/material.dart';
import 'dart:core';
class TestIconChange extends StatefulWidget {
  @override
  _TestIconChangeState createState() => _TestIconChangeState();
}

enum ChildType {text, button}

class _TestIconChangeState extends State<TestIconChange>
    with TickerProviderStateMixin {

  ChildType curChildType = ChildType.button;
  IconData _iconData = Icons.add;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        alignment: Alignment.center,

          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              AnimatedSwitcher(
                duration: Duration(milliseconds: 100),
                child: _buildButton(),
              ),
              RaisedButton(
                child: Text('Text Child'),
                onPressed: (() {
                  setState(() {
                    curChildType = ChildType.text;
                  });
                }),
              ),
              RaisedButton(
                child: Text('Button Child'),
                onPressed: (() {
                  setState(() {
                    curChildType = ChildType.button;
                  },);
                }),
              )
            ],
          ),
      ),
    );
  }

  Widget _buildButton() {
    if (curChildType == ChildType.text) {
      return Text('Dummy text');
    }
    else {
      return IconButton(
        icon: Icon(_iconData),
        onPressed: () {
          setState(() {
            _iconData = (_iconData == Icons.add) ? Icons.remove : _iconData = Icons.add;
          });
        },
      );
    }
  }
}

祝你好运!