setState не обновляет пользовательский интерфейс wiget - PullRequest
0 голосов
/ 09 февраля 2019

Я потратил несколько часов, пытаясь понять, почему нажатие на кнопку со значком не приводит к изменению его значка.

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 голосов
/ 09 февраля 2019

Когда вы вызываете 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;
          });
        },
      );
    }
  }
}

Удачи!

...