setState不会更新wiget UI

时间:2019-02-09 17:05:00

标签: animation dart flutter flutter-layout flutter-animation

我花了几个小时试图理解为什么单击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),
    );

  }
}

1 个答案:

答案 0 :(得分:1)

调用setState时,它将仅重建以build方法构建的小部件。

主要问题是您没有这样做。您没有使用_child方法重建build

您的代码中的这一行有误:if (_child == null) _child = _buildButton();

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

因此,我对您的代码进行了重构,并添加了ChildType来指示您想要显示的窗口小部件类型:文本或按钮。然后在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;
          });
        },
      );
    }
  }
}

祝你好运!