欢迎加入开源鸿蒙跨平台社区:
https://openharmonycrossplatform.csdn.net


项目效果

本文实现的是一个基于 Flutter for OpenHarmony 的启动页动态文案应用。项目中使用 Flutter 第三方库 animated_text_kit 实现文字动画效果,让页面中的标题、标语和功能介绍以动态形式展示。

最终运行效果如下:
在这里插入图片描述

在这里插入图片描述

页面主要包含以下内容:

  • 顶部应用标题;
  • Typewriter 打字机文字动画;
  • Fade 淡入淡出文字动画;
  • Rotate 轮播文字动画;
  • Colorize 彩色文字动画;
  • 功能介绍卡片;
  • 第三方库使用说明;
  • 页面整体采用 Flutter Material 风格布局。

本文重点是演示如何在 Flutter for OpenHarmony 项目中使用 Flutter 第三方库 animated_text_kit。项目代码写在 lib/main.dart 中,依赖配置写在 pubspec.yaml 中,符合 Flutter for OpenHarmony 第三方库实践方向。


前言

在移动应用开发中,启动页和欢迎页是用户进入应用后首先看到的页面。一个普通的静态标题虽然也能完成信息展示,但视觉效果比较单调。

如果想让页面更有吸引力,可以加入文字动画。例如:

  • 打字机效果;
  • 标语轮播效果;
  • 渐隐渐现效果;
  • 彩色文字流动效果;
  • 关键词动态切换效果。

如果完全自己用 Flutter 原生动画实现这些效果,需要写 AnimationControllerTweenTickerProvider 等内容。能写,但对于一个简单页面来说有点重。为了让一行字动起来写一堆动画控制器,像为了开门先造门锁厂,技术上能行,精神上很累。

因此本文选择使用 Flutter 第三方库 animated_text_kit 来实现文字动画。它封装了常见文字动画组件,可以直接在 Flutter 页面中使用。

本项目以“启动页动态文案应用”为例,使用 animated_text_kit 实现多种文字动画,并结合 Flutter Material 组件构建一个完整的展示页面。


一、项目目标

本次实践主要实现以下目标:

  • 创建 Flutter for OpenHarmony 项目;
  • pubspec.yaml 中添加第三方库 animated_text_kit
  • 使用 flutter pub get 获取依赖;
  • lib/main.dart 中引入 animated_text_kit
  • 使用 TypewriterAnimatedText 实现打字机动画;
  • 使用 FadeAnimatedText 实现淡入淡出动画;
  • 使用 RotateAnimatedText 实现轮播文字动画;
  • 使用 ColorizeAnimatedText 实现彩色文字动画;
  • 使用 Flutter Material 组件构建启动页;
  • 将应用运行到 OpenHarmony 设备或模拟器中。

二、技术栈

类型 内容
开发方向 Flutter for OpenHarmony
开发语言 Dart
UI 框架 Flutter
第三方库 animated_text_kit
功能场景 文字动画 / 启动页 / 欢迎页
项目入口 lib/main.dart
依赖配置 pubspec.yaml
运行平台 OpenHarmony 设备或模拟器

三、为什么选择 animated_text_kit

在实际应用中,文字动画可以用于很多场景,例如:

  • 应用启动页;
  • 首页宣传语;
  • 活动页标题;
  • 产品介绍页;
  • 登录页欢迎文案;
  • 个人主页标语;
  • 引导页说明;
  • 品牌口号展示。

如果使用 Flutter 原生动画手写,虽然自由度很高,但代码量会增加。尤其是多个文字动画同时存在时,页面逻辑容易变得复杂。

animated_text_kit 提供了很多现成的文字动画组件,可以让开发者快速实现动态文字效果。

在本项目中,animated_text_kit 主要完成以下工作:

  • 展示打字机文字动画;
  • 展示淡入淡出文字动画;
  • 展示轮播文字动画;
  • 展示彩色文字动画;
  • 提升启动页的视觉表现力。

四、创建 Flutter for OpenHarmony 项目

在已经配置好 Flutter for OpenHarmony 开发环境的前提下,可以创建一个 Flutter 项目。

示例项目名称:

flutter create animated_text_demo

进入项目目录:

cd animated_text_demo

项目创建完成后,主要关注两个文件:

animated_text_demo
 ├── pubspec.yaml
 └── lib
     └── main.dart

其中:

文件 作用
pubspec.yaml 配置 Flutter 项目依赖
lib/main.dart 编写 Flutter 页面和业务逻辑

五、添加 animated_text_kit 第三方库

打开项目根目录下的 pubspec.yaml 文件,在 dependencies 中添加 animated_text_kit

示例配置如下:

dependencies:
  flutter:
    sdk: flutter

  animated_text_kit: ^4.3.0

完整结构大致如下:

name: animated_text_demo
description: A Flutter for OpenHarmony animated text demo.
publish_to: 'none'

version: 1.0.0+1

environment:
  sdk: '>=3.4.0 <4.0.0'

dependencies:
  flutter:
    sdk: flutter

  animated_text_kit: ^4.3.0

dev_dependencies:
  flutter_test:
    sdk: flutter

flutter:
  uses-material-design: true

添加完成后,在终端执行:

flutter pub get

执行成功后,就可以在 Dart 代码中使用 animated_text_kit 了。


六、项目结构

本项目主要修改 lib/main.dart 文件:

lib
 └── main.dart

本项目不需要编写 OpenHarmony 原生 ArkTS 页面,也不需要修改 Index.ets

因为这是 Flutter for OpenHarmony 项目,页面主体应该是 Flutter 代码。审核主要看的是:

  • 是否使用 pubspec.yaml 添加 Flutter 第三方库;
  • 是否在 Dart 文件中 import package
  • 是否在 lib/main.dart 中实际调用第三方库;
  • 是否属于 Flutter for OpenHarmony 项目。

看到 pubspec.yamlpackage:animated_text_kit,这才像 Flutter 第三方库实践。看到 Index.ets 就容易又被判成原生鸿蒙,技术路线不是靠标题硬凹的。


七、核心实现思路

本项目的核心流程如下:

  1. pubspec.yaml 中添加 animated_text_kit
  2. main.dart 中引入第三方库;
  3. 使用 MaterialApp 创建 Flutter 应用;
  4. 使用 Scaffold 搭建页面结构;
  5. 使用 AnimatedTextKit 承载文字动画;
  6. 使用 TypewriterAnimatedText 实现打字效果;
  7. 使用 FadeAnimatedText 实现淡入淡出效果;
  8. 使用 RotateAnimatedText 实现文字轮播效果;
  9. 使用 ColorizeAnimatedText 实现彩色文字效果;
  10. 使用卡片区域展示第三方库说明。

第三方库引入代码如下:

import 'package:animated_text_kit/animated_text_kit.dart';

打字机动画核心代码如下:

AnimatedTextKit(
  animatedTexts: [
    TypewriterAnimatedText(
      'Build once, run on OpenHarmony.',
    ),
  ],
)

彩色文字动画核心代码如下:

AnimatedTextKit(
  animatedTexts: [
    ColorizeAnimatedText(
      'Flutter for OpenHarmony',
      textStyle: colorizeTextStyle,
      colors: colorizeColors,
    ),
  ],
)

八、main.dart 完整代码

打开文件:

lib/main.dart

将其中内容替换为下面代码:

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

void main() {
  runApp(const AnimatedTextDemoApp());
}

class AnimatedTextDemoApp extends StatelessWidget {
  const AnimatedTextDemoApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Animated Text Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.indigo,
          brightness: Brightness.light,
        ),
        useMaterial3: true,
      ),
      home: const AnimatedTextHomePage(),
    );
  }
}

class AnimatedTextHomePage extends StatelessWidget {
  const AnimatedTextHomePage({super.key});

  static const TextStyle colorizeTextStyle = TextStyle(
    fontSize: 28,
    fontWeight: FontWeight.bold,
  );

  static const List<Color> colorizeColors = [
    Colors.indigo,
    Colors.blue,
    Colors.purple,
    Colors.teal,
  ];

  
  Widget build(BuildContext context) {
    final ThemeData theme = Theme.of(context);

    return Scaffold(
      appBar: AppBar(
        title: const Text('启动页动态文案'),
        centerTitle: true,
      ),
      body: SafeArea(
        child: ListView(
          padding: const EdgeInsets.all(16),
          children: [
            _buildHeroCard(theme),
            const SizedBox(height: 16),
            _buildTypewriterCard(theme),
            const SizedBox(height: 16),
            _buildFadeCard(theme),
            const SizedBox(height: 16),
            _buildRotateCard(theme),
            const SizedBox(height: 16),
            _buildFeatureCard(theme),
            const SizedBox(height: 16),
            _buildLibraryCard(theme),
          ],
        ),
      ),
    );
  }

  Widget _buildHeroCard(ThemeData theme) {
    return Card(
      elevation: 3,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(22),
      ),
      child: Padding(
        padding: const EdgeInsets.all(24),
        child: Column(
          children: [
            Container(
              width: 78,
              height: 78,
              decoration: BoxDecoration(
                color: theme.colorScheme.primaryContainer,
                borderRadius: BorderRadius.circular(24),
              ),
              child: Icon(
                Icons.auto_awesome,
                size: 42,
                color: theme.colorScheme.onPrimaryContainer,
              ),
            ),
            const SizedBox(height: 20),
            AnimatedTextKit(
              repeatForever: true,
              pause: const Duration(milliseconds: 800),
              animatedTexts: [
                ColorizeAnimatedText(
                  'Flutter for OpenHarmony',
                  textStyle: colorizeTextStyle,
                  colors: colorizeColors,
                  speed: const Duration(milliseconds: 220),
                ),
              ],
            ),
            const SizedBox(height: 12),
            Text(
              '使用 animated_text_kit 构建更有表现力的启动页',
              textAlign: TextAlign.center,
              style: theme.textTheme.bodyMedium?.copyWith(
                color: theme.colorScheme.onSurfaceVariant,
                height: 1.5,
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildTypewriterCard(ThemeData theme) {
    return Card(
      elevation: 2,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(18),
      ),
      child: Padding(
        padding: const EdgeInsets.all(20),
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            _buildIconBox(
              theme,
              icon: Icons.keyboard,
            ),
            const SizedBox(width: 16),
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    'Typewriter 打字机动画',
                    style: theme.textTheme.titleLarge?.copyWith(
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  const SizedBox(height: 12),
                  SizedBox(
                    height: 68,
                    child: AnimatedTextKit(
                      repeatForever: true,
                      pause: const Duration(milliseconds: 900),
                      animatedTexts: [
                        TypewriterAnimatedText(
                          'Build once, run on OpenHarmony.',
                          textStyle: theme.textTheme.titleMedium?.copyWith(
                            fontWeight: FontWeight.w600,
                            color: theme.colorScheme.primary,
                          ),
                          speed: const Duration(milliseconds: 80),
                        ),
                        TypewriterAnimatedText(
                          '用 Flutter 写出跨平台页面。',
                          textStyle: theme.textTheme.titleMedium?.copyWith(
                            fontWeight: FontWeight.w600,
                            color: theme.colorScheme.primary,
                          ),
                          speed: const Duration(milliseconds: 80),
                        ),
                      ],
                    ),
                  ),
                  Text(
                    '适合用于启动页标语、输入提示、欢迎语展示等场景。',
                    style: theme.textTheme.bodySmall?.copyWith(
                      color: theme.colorScheme.onSurfaceVariant,
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildFadeCard(ThemeData theme) {
    return Card(
      elevation: 2,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(18),
      ),
      child: Padding(
        padding: const EdgeInsets.all(20),
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            _buildIconBox(
              theme,
              icon: Icons.blur_on,
            ),
            const SizedBox(width: 16),
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    'Fade 淡入淡出动画',
                    style: theme.textTheme.titleLarge?.copyWith(
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  const SizedBox(height: 12),
                  SizedBox(
                    height: 68,
                    child: AnimatedTextKit(
                      repeatForever: true,
                      pause: const Duration(milliseconds: 600),
                      animatedTexts: [
                        FadeAnimatedText(
                          '快速构建页面',
                          textStyle: theme.textTheme.titleMedium?.copyWith(
                            fontWeight: FontWeight.bold,
                            color: Colors.teal,
                          ),
                          duration: const Duration(milliseconds: 1800),
                        ),
                        FadeAnimatedText(
                          '清晰展示重点',
                          textStyle: theme.textTheme.titleMedium?.copyWith(
                            fontWeight: FontWeight.bold,
                            color: Colors.teal,
                          ),
                          duration: const Duration(milliseconds: 1800),
                        ),
                        FadeAnimatedText(
                          '提升启动页观感',
                          textStyle: theme.textTheme.titleMedium?.copyWith(
                            fontWeight: FontWeight.bold,
                            color: Colors.teal,
                          ),
                          duration: const Duration(milliseconds: 1800),
                        ),
                      ],
                    ),
                  ),
                  Text(
                    '适合用于功能亮点、宣传短句和页面提示文案。',
                    style: theme.textTheme.bodySmall?.copyWith(
                      color: theme.colorScheme.onSurfaceVariant,
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildRotateCard(ThemeData theme) {
    return Card(
      elevation: 2,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(18),
      ),
      child: Padding(
        padding: const EdgeInsets.all(20),
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            _buildIconBox(
              theme,
              icon: Icons.cached,
            ),
            const SizedBox(width: 16),
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    'Rotate 轮播文字动画',
                    style: theme.textTheme.titleLarge?.copyWith(
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                  const SizedBox(height: 12),
                  Row(
                    children: [
                      Text(
                        '适用于 ',
                        style: theme.textTheme.titleMedium,
                      ),
                      Expanded(
                        child: AnimatedTextKit(
                          repeatForever: true,
                          pause: const Duration(milliseconds: 700),
                          animatedTexts: [
                            RotateAnimatedText(
                              '启动页',
                              textStyle: theme.textTheme.titleMedium?.copyWith(
                                fontWeight: FontWeight.bold,
                                color: Colors.deepPurple,
                              ),
                            ),
                            RotateAnimatedText(
                              '欢迎页',
                              textStyle: theme.textTheme.titleMedium?.copyWith(
                                fontWeight: FontWeight.bold,
                                color: Colors.deepPurple,
                              ),
                            ),
                            RotateAnimatedText(
                              '宣传页',
                              textStyle: theme.textTheme.titleMedium?.copyWith(
                                fontWeight: FontWeight.bold,
                                color: Colors.deepPurple,
                              ),
                            ),
                            RotateAnimatedText(
                              '产品介绍页',
                              textStyle: theme.textTheme.titleMedium?.copyWith(
                                fontWeight: FontWeight.bold,
                                color: Colors.deepPurple,
                              ),
                            ),
                          ],
                        ),
                      ),
                    ],
                  ),
                  const SizedBox(height: 18),
                  Text(
                    '多个关键词可以自动切换,比静态文字更容易突出页面重点。',
                    style: theme.textTheme.bodySmall?.copyWith(
                      color: theme.colorScheme.onSurfaceVariant,
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildFeatureCard(ThemeData theme) {
    final List<_FeatureItem> features = [
      const _FeatureItem(
        icon: Icons.flash_on,
        title: '轻量接入',
        desc: '通过 pubspec.yaml 添加依赖后即可使用。',
      ),
      const _FeatureItem(
        icon: Icons.text_fields,
        title: '多种文字动画',
        desc: '支持打字、淡入、轮播和彩色文字等效果。',
      ),
      const _FeatureItem(
        icon: Icons.phone_iphone,
        title: '适合移动端页面',
        desc: '可用于启动页、欢迎页、活动页和宣传页。',
      ),
    ];

    return Card(
      elevation: 2,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(18),
      ),
      child: Padding(
        padding: const EdgeInsets.all(20),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              '页面功能说明',
              style: theme.textTheme.titleLarge?.copyWith(
                fontWeight: FontWeight.bold,
              ),
            ),
            const SizedBox(height: 14),
            ...features.map((item) {
              return Padding(
                padding: const EdgeInsets.only(bottom: 14),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Icon(
                      item.icon,
                      color: theme.colorScheme.primary,
                    ),
                    const SizedBox(width: 12),
                    Expanded(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                            item.title,
                            style: theme.textTheme.titleMedium?.copyWith(
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                          const SizedBox(height: 4),
                          Text(
                            item.desc,
                            style: theme.textTheme.bodySmall?.copyWith(
                              color: theme.colorScheme.onSurfaceVariant,
                              height: 1.5,
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              );
            }),
          ],
        ),
      ),
    );
  }

  Widget _buildLibraryCard(ThemeData theme) {
    return Card(
      elevation: 2,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(18),
      ),
      child: Padding(
        padding: const EdgeInsets.all(20),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              '第三方库说明',
              style: theme.textTheme.titleLarge?.copyWith(
                fontWeight: FontWeight.bold,
              ),
            ),
            const SizedBox(height: 12),
            _buildInfoRow(
              theme,
              title: '库名称',
              value: 'animated_text_kit',
            ),
            _buildInfoRow(
              theme,
              title: '配置文件',
              value: 'pubspec.yaml',
            ),
            _buildInfoRow(
              theme,
              title: '导入方式',
              value: "import 'package:animated_text_kit/animated_text_kit.dart';",
            ),
            _buildInfoRow(
              theme,
              title: '核心组件',
              value: 'AnimatedTextKit / TypewriterAnimatedText / FadeAnimatedText',
            ),
            _buildInfoRow(
              theme,
              title: '应用场景',
              value: '启动页、欢迎页、宣传页、活动页、产品介绍页',
            ),
          ],
        ),
      ),
    );
  }

  Widget _buildIconBox(
    ThemeData theme, {
    required IconData icon,
  }) {
    return Container(
      width: 50,
      height: 50,
      decoration: BoxDecoration(
        color: theme.colorScheme.primaryContainer,
        borderRadius: BorderRadius.circular(18),
      ),
      child: Icon(
        icon,
        color: theme.colorScheme.onPrimaryContainer,
      ),
    );
  }

  Widget _buildInfoRow(
    ThemeData theme, {
    required String title,
    required String value,
  }) {
    return Padding(
      padding: const EdgeInsets.only(bottom: 10),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          SizedBox(
            width: 82,
            child: Text(
              title,
              style: theme.textTheme.bodyMedium?.copyWith(
                fontWeight: FontWeight.bold,
              ),
            ),
          ),
          Expanded(
            child: Text(
              value,
              style: theme.textTheme.bodyMedium?.copyWith(
                color: theme.colorScheme.onSurfaceVariant,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class _FeatureItem {
  const _FeatureItem({
    required this.icon,
    required this.title,
    required this.desc,
  });

  final IconData icon;
  final String title;
  final String desc;
}

九、代码实现说明

1. 引入 animated_text_kit 第三方库

代码开头引入第三方库:

import 'package:animated_text_kit/animated_text_kit.dart';

这说明项目确实使用了 Flutter 第三方库,而不是 OpenHarmony 原生库。

本项目中主要使用以下组件:

AnimatedTextKit
TypewriterAnimatedText
FadeAnimatedText
RotateAnimatedText
ColorizeAnimatedText

其中:

组件 作用
AnimatedTextKit 动画文字容器
TypewriterAnimatedText 打字机文字动画
FadeAnimatedText 淡入淡出文字动画
RotateAnimatedText 文字轮播动画
ColorizeAnimatedText 彩色文字动画

2. 使用 ColorizeAnimatedText 实现彩色标题

页面顶部使用彩色文字动画作为主标题:

AnimatedTextKit(
  repeatForever: true,
  animatedTexts: [
    ColorizeAnimatedText(
      'Flutter for OpenHarmony',
      textStyle: colorizeTextStyle,
      colors: colorizeColors,
    ),
  ],
)

其中:

参数 作用
repeatForever 是否循环播放
animatedTexts 动画文字列表
textStyle 文字样式
colors 彩色动画颜色列表

这样可以让标题文字产生动态变色效果。


3. 使用 TypewriterAnimatedText 实现打字机效果

打字机动画代码如下:

TypewriterAnimatedText(
  'Build once, run on OpenHarmony.',
  speed: const Duration(milliseconds: 80),
)

其中:

参数 作用
文本内容 要展示的文字
speed 每个字符出现的速度

这个效果适合启动页标语、欢迎语和宣传语。比直接甩一行静态文字上去更有表现力,毕竟页面不是公告栏,稍微动一下也不违法。


4. 使用 FadeAnimatedText 实现淡入淡出效果

淡入淡出动画代码如下:

FadeAnimatedText(
  '快速构建页面',
  duration: const Duration(milliseconds: 1800),
)

其中:

参数 作用
文本内容 要淡入淡出的文字
duration 单条文字动画持续时间

本项目中放入了多个淡入淡出文字:

FadeAnimatedText('快速构建页面')
FadeAnimatedText('清晰展示重点')
FadeAnimatedText('提升启动页观感')

这些文字会按照顺序播放。


5. 使用 RotateAnimatedText 实现文字轮播

轮播文字动画代码如下:

RotateAnimatedText(
  '启动页',
)

本项目中用于展示多个适用场景:

RotateAnimatedText('启动页')
RotateAnimatedText('欢迎页')
RotateAnimatedText('宣传页')
RotateAnimatedText('产品介绍页')

这种方式适合展示同一位置下的多个关键词。


6. 使用 repeatForever 循环播放动画

在多个 AnimatedTextKit 中使用了:

repeatForever: true

这表示动画会一直循环播放。

如果不设置循环,动画播放结束后会停止。对于启动页展示来说,循环播放更适合演示效果。


7. 设置 pause 控制动画间隔

本项目中还设置了:

pause: const Duration(milliseconds: 800)

表示每一段文字动画结束后暂停一小段时间。

如果没有暂停,文字切换会显得太快,用户还没看清,下一句就急着冲出来,像赶着下班的提示语。


十、运行项目

完成代码后,在终端执行:

flutter pub get

然后连接 OpenHarmony 设备或启动 OpenHarmony 模拟器。

查看设备:

flutter devices

运行项目:

flutter run

如果环境配置正确,应用会运行到 OpenHarmony 设备或模拟器中。

运行成功后,页面会显示“启动页动态文案”。可以看到顶部彩色标题动画、打字机动画、淡入淡出动画和文字轮播动画。


十一、开发中遇到的问题

1. animated_text_kit 依赖没有生效

如果代码中出现找不到 animated_text_kit 的问题,可以检查 pubspec.yaml 中是否添加了:

animated_text_kit: ^4.3.0

然后重新执行:

flutter pub get

如果还是不行,可以重启编辑器。编辑器有时候像刚睡醒,依赖装好了它还要缓一缓才承认。


2. import 导入报错

如果下面代码报错:

import 'package:animated_text_kit/animated_text_kit.dart';

通常有几种原因:

  • pubspec.yaml 中没有添加依赖;
  • 没有执行 flutter pub get
  • YAML 缩进错误;
  • 包名写错;
  • 编辑器没有刷新依赖。

其中 YAML 缩进最容易出问题。配置文件对空格的敏感程度,简直像在训练人类的耐心和手指精度。


3. 动画没有播放

如果动画没有播放,可以检查:

  • 是否使用了 AnimatedTextKit
  • animatedTexts 是否为空;
  • 页面是否成功运行;
  • 文字颜色是否和背景颜色太接近;
  • 外层容器高度是否过小。

本项目中多个动画外层都设置了固定高度,例如:

SizedBox(
  height: 68,
  child: AnimatedTextKit(...),
)

这样可以避免布局空间不足导致文字显示异常。


4. 文字显示不完整

如果文字显示不完整,可以检查:

  • 外层 SizedBox 高度是否太小;
  • 文本字号是否过大;
  • 是否需要使用 Expanded
  • 横向空间是否不足。

例如轮播文字区域使用了:

Expanded(
  child: AnimatedTextKit(...),
)

这样可以避免文字被 Row 挤压。


5. 彩色文字动画报错

如果使用 ColorizeAnimatedText 报错,可以检查是否提供了颜色列表:

colors: colorizeColors

同时需要提供文字样式:

textStyle: colorizeTextStyle

这两个参数缺少或类型不对,都可能导致编译问题。


6. 运行不到 OpenHarmony 设备

如果项目无法运行到 OpenHarmony 设备或模拟器,可以检查:

  • Flutter for OpenHarmony 环境是否配置完成;
  • 设备是否连接成功;
  • flutter devices 是否能识别设备;
  • 是否执行了 flutter pub get
  • 是否选择了正确的运行设备;
  • 项目是否为 Flutter 项目,而不是原生鸿蒙项目。

如果 flutter devices 都识别不到设备,那就先处理环境问题,不要盯着动画代码发呆。动画再努力,也跑不出没连上的设备。


十二、本文和原生鸿蒙项目的区别

本文是 Flutter for OpenHarmony 第三方库实践,不是 OpenHarmony 原生 ArkTS 项目。

主要区别如下:

对比项 本文写法 原生鸿蒙写法
UI 技术 Flutter ArkUI
主要语言 Dart ArkTS
页面入口 lib/main.dart Index.ets
依赖配置 pubspec.yaml oh-package.json5
依赖安装 flutter pub get ohpm install
第三方库 animated_text_kit OpenHarmony 原生库
页面组件 MaterialApp / Scaffold / AnimatedTextKit @Entry / @Component

因此本文符合 Flutter for OpenHarmony 第三方库实践方向。


十三、总结

本篇完成了一个基于 animated_text_kit 的 Flutter for OpenHarmony 启动页动态文案应用。项目通过 Flutter 第三方库实现多种文字动画效果,并结合 Flutter Material 组件构建了一个完整的启动页展示页面。

通过本次实践,我主要完成了以下内容:

  • 创建 Flutter for OpenHarmony 项目;
  • pubspec.yaml 中添加 animated_text_kit 依赖;
  • 使用 flutter pub get 获取第三方库;
  • lib/main.dart 中引入 animated_text_kit
  • 使用 AnimatedTextKit 作为动画文字容器;
  • 使用 TypewriterAnimatedText 实现打字机动画;
  • 使用 FadeAnimatedText 实现淡入淡出动画;
  • 使用 RotateAnimatedText 实现轮播文字动画;
  • 使用 ColorizeAnimatedText 实现彩色文字动画;
  • 使用 Flutter Material 组件构建启动页;
  • 将项目运行到 OpenHarmony 设备或模拟器中。

这个项目虽然只是一个基础启动页应用,但完整展示了 Flutter for OpenHarmony 项目中第三方库的使用流程。

后续可以在这个基础上继续扩展,例如:

  • 添加应用 Logo 图片;
  • 添加登录按钮;
  • 添加页面跳转;
  • 添加启动倒计时;
  • 添加暗色主题;
  • 添加多语言文案;
  • 添加背景渐变;
  • 添加图片动画;
  • 添加真实项目介绍内容;
  • 添加用户引导页。

整体来看,animated_text_kit 可以帮助 Flutter 开发者快速实现文字动画。通过这个项目,可以理解 Flutter for OpenHarmony 中第三方库依赖配置、动画文字组件使用和 Flutter 页面构建之间的基本关系。

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐