You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter首启动动画文本翻译加载异常问题求助

解决Flutter首次启动时AnimatedTextKit翻译内容显示异常的问题

问题根源

  • didChangeDependencies是同步生命周期方法,你添加async关键字后,方法执行变为异步,导致_frase的赋值时机晚于AnimatedTextKit的初始化,动画直接使用了初始的_frase值开始播放。
  • 即便后续_frase被赋值为正确翻译内容,由于没有调用setState()触发UI重建,AnimatedTextKit不会更新文本。切换窗口时触发了组件重建,此时_frase已为正确值,动画就能正常显示。

解决方案

方案一:用FutureBuilder等待翻译就绪

将翻译逻辑封装为异步方法,确保动画在翻译内容准备完成后再渲染:

// 封装获取翻译文本的异步方法
Future<String> _getTranslatedText() async {
  await Future.delayed(Duration.zero); // 等待依赖初始化完成
  final localizations = AppLocalizations.of(context)!;
  final month = DateFormat.MMMM(localizations.codice)
      .format(DateTime.now())
      .capitalize();
  return "${localizations.ext} $month $annoAttuale";
}

@override
Widget build(BuildContext context) {
  return FutureBuilder<String>(
    future: _getTranslatedText(),
    initialData: "", // 初始空文本或自定义占位符
    builder: (context, snapshot) {
      if (snapshot.hasData && snapshot.data!.isNotEmpty) {
        return AnimatedTextKit(
          isRepeatingAnimation: false,
          animatedTexts: [
            TypewriterAnimatedText(
              snapshot.data!,
              textAlign: TextAlign.center,
              textStyle: const TextStyle(
                fontWeight: FontWeight.bold,
                fontSize: 21,
              ),
              speed: const Duration(milliseconds: 30),
            ),
          ],
        );
      }
      // 加载中占位UI
      return const SizedBox.shrink();
    },
  );
}

方案二:修正didChangeDependencies的状态更新

移除async关键字(生命周期方法不能异步),直接赋值并调用setState()触发重建:

@override
void didChangeDependencies() {
  super.didChangeDependencies();
  final localizations = AppLocalizations.of(context)!;
  final month = DateFormat.MMMM(localizations.codice)
      .format(DateTime.now())
      .capitalize();
  final newFrase = "${localizations.ext} $month $annoAttuale";
  // 仅内容变化时更新,避免不必要重建
  if (newFrase != _frase) {
    setState(() {
      _frase = newFrase;
    });
  }
}

@override
Widget build(BuildContext context) {
  return _frase.isEmpty
      ? const SizedBox.shrink()
      : AnimatedTextKit(
          isRepeatingAnimation: false,
          animatedTexts: [
            TypewriterAnimatedText(
              _frase,
              textAlign: TextAlign.center,
              textStyle: const TextStyle(
                fontWeight: FontWeight.bold,
                fontSize: 21,
              ),
              speed: const Duration(milliseconds: 30),
            ),
          ],
        );
}

方案三:用ValueNotifier实现响应式更新

通过ValueNotifier监听文本变化,让AnimatedTextKit自动响应更新:

final ValueNotifier<String> _fraseNotifier = ValueNotifier("");

@override
void didChangeDependencies() {
  super.didChangeDependencies();
  final localizations = AppLocalizations.of(context)!;
  final month = DateFormat.MMMM(localizations.codice)
      .format(DateTime.now())
      .capitalize();
  _fraseNotifier.value = "${localizations.ext} $month $annoAttuale";
}

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

@override
Widget build(BuildContext context) {
  return ValueListenableBuilder<String>(
    valueListenable: _fraseNotifier,
    builder: (context, frase, child) {
      return frase.isEmpty
          ? const SizedBox.shrink()
          : AnimatedTextKit(
              isRepeatingAnimation: false,
              animatedTexts: [
                TypewriterAnimatedText(
                  frase,
                  textAlign: TextAlign.center,
                  textStyle: const TextStyle(
                    fontWeight: FontWeight.bold,
                    fontSize: 21,
                  ),
                  speed: const Duration(milliseconds: 30),
                ),
              ],
            );
    },
  );
}

内容的提问来源于stack exchange,提问作者Jonathan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 10:46:18