在下面的代码中,我希望仅当按下FlatButton时,AnimatedSwitcher下的Text才能动画,但是它为我在TextField中输入的每个单个字符设置动画。由于TextField在其onChanged方法中具有setState,因此每次输入字符都会触发动画。
如何防止AnimatedSwitcher每次调用setState方法时都进行重建,并且仅在其子项的值已更新时才进行重建?

class _TestScreenState extends State<TestScreen> {
  int _counter = 0;
  int _value = 0;
  TextEditingController controller = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          AnimatedSwitcher(
            duration: Duration(milliseconds: 300),
            child: Text(_counter.toString(),
                key: UniqueKey(), style: TextStyle(fontSize: 50)),
            transitionBuilder: (Widget child, Animation<double> animation) {
              return FadeTransition(
                opacity: animation,
                child: ScaleTransition(
                  scale: animation.status == AnimationStatus.dismissed
                      ? Tween<double>(begin: .5, end: 1).animate(animation)
                      : AlwaysStoppedAnimation(1.0),
                  child: child,
                ),
              );
            },
          ),
          Padding(
            padding: EdgeInsets.all(10),
            child: Text(
              _value.toString(),
              style: TextStyle(fontSize: 20),
            ),
          ),
          Padding(
            padding: EdgeInsets.all(10),
            child: TextField(
              controller: controller,
              keyboardType: TextInputType.number,
              textAlign: TextAlign.center,
              onChanged: (val) {
                setState(() {
                  _value = int.parse(val) * 5;
                });
              },
              decoration: InputDecoration(labelText: "Enter amount"),
            ),
          ),
          Padding(
            padding: EdgeInsets.all(10),
            child: FlatButton(
              onPressed: () => setState(() {
                _counter = int.parse(controller.text) * 5;
              }),
              child: Text('Tap to change value'),
            ),
          )
        ],
      ),
    );
  }
}

最佳答案

试试这个

class _TestScreenState extends State<TestScreen> {
  int _counter = 0;
  int _value = 0;
  TextEditingController controller = TextEditingController();

  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          AnimatedSwitcher(
            duration: Duration(milliseconds: 300),
            child: Text(_counter.toString(), key: ValueKey<int>(_counter), style: TextStyle(fontSize: 50)),
            transitionBuilder: (Widget child, Animation<double> animation) {
              return FadeTransition(
                opacity: animation,
                child: ScaleTransition(
                  scale: animation.status == AnimationStatus.dismissed
                      ? Tween<double>(begin: .5, end: 1).animate(animation)
                      : AlwaysStoppedAnimation(1.0),
                  child: child,
                ),
              );
            },
          ),
          Padding(
            padding: EdgeInsets.all(10),
            child: Text(
              _value.toString(),
              style: TextStyle(fontSize: 20),
            ),
          ),
          Padding(
            padding: EdgeInsets.all(10),
            child: TextField(
              controller: controller,
              keyboardType: TextInputType.number,
              textAlign: TextAlign.center,
              onChanged: (val) {
                setState(() {
                  _value = int.parse(val) * 5;
                });
              },
              decoration: InputDecoration(labelText: "Enter amount"),
            ),
          ),
          Padding(
            padding: EdgeInsets.all(10),
            child: FlatButton(
              onPressed: () => setState(() {
                _counter = int.parse(controller.text) * 5;
              }),
              child: Text('Tap to change value'),
            ),
          )
        ],
      ),
    );
  }
}

关于flutter - 每次我输入文本字段时,Flutter AnimatedSwitcher都会重建,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/62558063/

10-17 00:19