Flutter 不更新其动画文本小部件 (Animated_Text_kit)

Tus*_*har 2 android dart flutter flutter-dependencies flutter-layout

所以这是我从 json 获取数据并更新 UI 的主要代码。\n我已在与问题相关的代码所在的位置放置了“//Area of​​ Interest”注释。

\n
 class MainScreen extends StatefulWidget {\n  final curLocdata;\n  MainScreen({this.curLocdata});\n\n  @override\n  _MainScreenState createState() => _MainScreenState();\n}\n\nclass _MainScreenState extends State<MainScreen> {\n  Weather weather = Weather();\n\n  var cityName;\n  int temp;\n  int temp_min;\n  int temp_max;\n  Icon weatherIcon;\n//Area of Interest 1\n  RotateAnimatedTextKit textSum;//created a widget of RotateAnimatedTextKit library.\n  String st;\n//Area of Interest 2\n  @override\n  void initState() {\n    // TODO: implement initState\n    super.initState();\n    updateUI(widget.curLocdata);//calling update function to rebuild my UI state with new data\n  }\n\n  void updateUI(data) {\n    setState(() {\n      if (data == null) {\n        temp = 0;\n        cityName = 'Error';\n        weatherIcon = Icon(Icons.error);\n        return;\n      }\n      cityName = data['name'];\n      temp = data['main']['temp'].toInt();\n      temp_min = data['main']['temp_min'].toInt();\n      temp_max = data['main']['temp_max'].toInt();\n      var condition = data['weather'][0]['id'];\n      weatherIcon = weather.getIcon(condition);\n      textSum = weather.getMessage(temp);//Area of Interest 3\n      st = weather.subtext(condition);\n    });\n  }\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      body: Container(\n        child: SafeArea(\n          child: Column(\n            children: <Widget>[\n              Container(\n                child: Row(\n                  mainAxisAlignment: MainAxisAlignment.spaceBetween,\n                  children: <Widget>[\n                    FlatButton(\n                      onPressed: () async {\n                        updateUI(await Network().getData());\n                      },\n                      child: Icon(\n                        FontAwesomeIcons.locationArrow,\n                      ),\n                    ),\n                    SizedBox(\n                      width: 180.0,\n                      child: TextLiquidFill(\n                        waveDuration: Duration(seconds: 3),\n                        loadDuration: Duration(seconds: 10),\n                        text: 'OpenWeather',\n                        waveColor: Colors.red,\n                        boxBackgroundColor: Color(0xFF1B1B1D),\n                        textStyle: TextStyle(\n                          fontSize: 30.0,\n                          fontWeight: FontWeight.bold,\n                          fontFamily: 'Source Sans Pro',\n                        ),\n                        boxHeight: 50.0,\n                      ),\n                    ),\n                    FlatButton(\n                      onPressed: () async {\n                        String SName = await Navigator.push(context,\n                            MaterialPageRoute(builder: (context) {\n                          return Search();\n                        }));\n                        if (SName != null) {\n                          updateUI(await Network().getDataName(\n                              SName)); \n                        }\n                      },\n                      child: Icon(\n                        Icons.add,\n                        color: Colors.white,\n                        size: 40,\n                      ),\n                    ),\n                  ],\n                ),\n              ),\n              Padding(\n                  padding: EdgeInsets.fromLTRB(50, 50, 50, 0),\n                  child: Row(\n                    children: <Widget>[\n                      SizedBox(\n//                margin: EdgeInsets.fromLTRB(0, 50, 260, 0),\n                        child: TypewriterAnimatedTextKit(\n                          totalRepeatCount: 200,\n                          isRepeatingAnimation: true,\n                          speed: Duration(milliseconds: 700),\n                          text: [cityName,],\n                          textAlign: TextAlign.left,\n                          textStyle: TextStyle(\n                            fontSize: 20,\n                            fontFamily: 'Source Sans Pro',\n                          ),\n                        ),\n                      ),\n                    ],\n                  )),\n              Expanded(\n                flex: 9,\n                child: Container(\n                  margin: EdgeInsets.fromLTRB(50, 30, 50, 80),\n                  child: Column(\n                    crossAxisAlignment: CrossAxisAlignment.stretch,\n                    //mainAxisAlignment: MainAxisAlignment.spaceEvenly,\n                    children: <Widget>[\n                      Expanded(\n                        flex: 2,\n                        child: Padding(\n                          padding: EdgeInsets.only(left: 20),\n                          child: Text(\n                            '$temp\xc2\xb0',\n                            style: TextStyle(\n                              fontSize: 80,\n                              fontWeight: FontWeight.bold,\n                              fontFamily: 'Source Sans Pro',\n                            ),\n                          ),\n                        ),\n                      ),\n                      Expanded(\n                        flex: 2,\n                        child: Padding(\n                          padding: EdgeInsets.only(left: 20),\n                          child: Text(\n                            st,\n                            style: TextStyle(\n                                fontSize: 30,\n                                fontFamily: 'Source Sans Pro',\n                                color: Colors.grey[500]),\n                          ),\n                        ),\n                      ),\n                      Padding(\n                        padding: EdgeInsets.fromLTRB(20, 0, 0, 50),\n                        child: Container(\n                          child: textSum,//Used this textSum to show my animated text. problem\nArea of Interest 4\n                        ),\n                      ),\n                      Expanded(\n                        child: SizedBox(\n                          //width: double.infinity,\n                          //height: 100,\n                          child: Divider(\n                            color: Colors.red,\n                          ),\n                        ),\n                      ),\n                      Row(\n                        children: <Widget>[\n                          Expanded(\n                            child: Padding(\n                              padding: EdgeInsets.fromLTRB(20, 0, 0, 38),\n                              child: Text(\n                                '$temp_min\xc2\xb0 - $temp_max\xc2\xb0',\n                                style: TextStyle(\n                                  fontSize: 20,\n                                  color: Colors.grey[500],\n                                  fontFamily: 'Source Sans Pro',\n                                ),\n                              ),\n                            ),\n                          ),\n                          Expanded(\n                            child: Padding(\n                              padding: EdgeInsets.fromLTRB(20, 0, 0, 20),\n                              //padding: const EdgeInsets.all(8.0),\n                              child: AvatarGlow(\n                                endRadius: 30.0, //required\n                                child: Material(\n                                  //required\n                                  elevation: 0.0,\n                                  shape: CircleBorder(),\n                                  child: CircleAvatar(\n                                      //backgroundColor: Colors.grey[100],\n                                      child: weatherIcon\n                                      // radius: 40.0,\n                                      //shape: BoxShape.circle\n                                      ),\n                                ),\n                              ),\n                            ),\n                          )\n                        ],\n                      )`enter code here`\n                    ],\n                  ),\n                  decoration: BoxDecoration(\n                    borderRadius: BorderRadius.circular(10),\n                    color: Color(0xFF0C0C0C),\n                  ),\n                ),\n              ),\n
Run Code Online (Sandbox Code Playgroud)\n

现在,我根据条件返回 RotateAnimatedTextKit 小部件的 Weather.dart 文件

\n
    class Weather{\n\n//This return RotateAnimatedTextKit which is then held by textSum and is put as a child inside a container in MainScreen\n\n  RotateAnimatedTextKit getMessage(int temp) {\n    if (temp > 25) {\n      return RotateAnimatedTextKit(\n          isRepeatingAnimation: true,\n          totalRepeatCount: 200,\n          transitionHeight: 40,\n          text: ['It\\'s ','time and','drink plenty','of water'],\n          textStyle: TextStyle(fontSize: 30.0, fontFamily: "Source Sans Pro", color: Colors.red),\n          textAlign: TextAlign.start,\n          alignment: AlignmentDirectional.topStart // or Alignment.topLeft\n      );\n\n      \n    } else if (temp > 20) {\n      return RotateAnimatedTextKit(\n          isRepeatingAnimation: true,\n          totalRepeatCount: 200,\n          transitionHeight: 50,\n          text: ['Time for','shorts','','but keep','some warm','clothes handy'],\n          textStyle: TextStyle(fontSize: 30.0, fontFamily: "Source Sans Pro", color: Colors.red),\n          textAlign: TextAlign.start,\n          alignment: AlignmentDirectional.bottomStart// or Alignment.topLeft\n      );\n      \n    } else if (temp < 10) {\n      return RotateAnimatedTextKit(\n          isRepeatingAnimation: true,\n          totalRepeatCount: 200,\n          transitionHeight: 50,\n          text: ['You\\'ll need','a ','and','a ','and a hot', 'soup and turkey'],\n          textStyle: TextStyle(fontSize: 30.0, fontFamily: "Source Sans Pro", color: Colors.red),\n          textAlign: TextAlign.start,\n          alignment: AlignmentDirectional.bottomStart // or Alignment.topLeft\n      );\n     \n    } else {\n      return RotateAnimatedTextKit(\n          isRepeatingAnimation: true,\n          transitionHeight: 50,\n          totalRepeatCount: 200,\n          text: ['Bring a','','just in case','and also avoid', 'cold breeze','and cold drinks'],\n          textStyle: TextStyle(fontSize: 30.0, fontFamily: "Source Sans Pro", color: Colors.red),\n          textAlign: TextAlign.start,\n          alignment: AlignmentDirectional.bottomStart // or Alignment.topLeft\n      );\n      \n    }\n  }\n
Run Code Online (Sandbox Code Playgroud)\n

问题是,即使条件不同,用户界面也不会更新。那么有什么解决方案可以解决为什么小部件树不更新的问题吗?但它只运行默认文本。此外,cityName下面的TextLiquidFill不会更新。

\n

Ser*_*rte 8

简短回答: 使用按键

例子:

import 'package:animated_text_kit/animated_text_kit.dart';
import 'package:flutter/material.dart';

class MyAnimatedText extends StatefulWidget {
  const MyAnimatedText({Key? key}) : super(key: key);
  @override
  State<MyAnimatedText> createState() => _MyAnimatedTextState();
}

class _MyAnimatedTextState extends State<MyAnimatedText> {
  bool isDarkMode = true;

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(30),
          color: isDarkMode ? Colors.grey[850] : Colors.amber[300]),
      child: Column(
        children: [
          Container(
              alignment: Alignment.topRight,
              child: IconButton(
                  onPressed: () {
                    setState(() {
                      isDarkMode = !isDarkMode;
                    });
                  },
                  icon: Icon(isDarkMode ? Icons.light_mode : Icons.dark_mode))),
          Padding(
            padding: const EdgeInsets.all(15.0),
            child: AnimatedTextKit(
              key: ValueKey<bool>(isDarkMode),
              animatedTexts: [
                TypewriterAnimatedText(
                  isDarkMode ? 'Have a nice evening ;)' : 'Have a nice day :)',
                  cursor: isDarkMode ?'>':'<',
                  textStyle: TextStyle(
                      fontSize: 38,
                      color: isDarkMode ? Colors.amber[300] : Colors.grey[850]),
                  speed: const Duration(milliseconds: 100),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

结果: 在此输入图像描述

背景资料

当我尝试实现暗/亮变化时,我遇到了同样的问题。背景颜色在其他小部件中定义并更改,字体颜色在 TypewriterAnimatedText 部件中定义并仅在第二个循环中更改。运行动画中颜色没有变化。

解决方案:使用 Keys 动画不会改变,因为 Flutter 试图保持 StatefulWidget 的状态,而 AnimatedTextKit 是一个 Stateful Widget。要强制重建,您可以使用密钥。

可以在这里找到一篇不错的文章:How to Force a Widget to redraw in Flutter?