前言

Flutter是Google开发的开源UI工具包,支持用一套代码构建iOSAndroidWebWindowsmacOSLinux六大平台应用,实现"一次编写,多处运行"。

OpenHarmony是由开放原子开源基金会运营的分布式操作系统,为全场景智能设备提供统一底座,具有多设备支持、模块化设计、分布式能力和开源开放等特性。

Flutter for OpenHarmony技术方案使开发者能够:

  1. 复用Flutter现有代码(Skia渲染引擎、热重载、丰富组件库)
  2. 快速构建符合OpenHarmony规范的UI
  3. 降低多端开发成本
  4. 利用Dart生态插件资源加速生态建设

先看效果

Flutter web试试预览

在这里插入图片描述

在鸿蒙真机 上模拟器上成功运行后的效果

在这里插入图片描述


目录

本文档旨在帮助初学者理解本项目结构、核心组件实现细节以及如何使用这些组件构建精美的表单界面。

1. 项目结构

项目代码主要位于 lib 目录下,结构如下:

lib/
├── main.dart                  # 程序入口文件
├── pages/                     # 页面目录
│   └── signup_form_page.dart  # 注册表单页面(核心页面)
└── widgets/                   # 自定义组件目录
    ├── cool_button.dart       # 自定义按钮组件
    └── cool_text_field.dart   # 自定义文本输入框组件

2. 程序入口 (main.dart)

main.dart 是 Flutter 应用的起点。

主要功能

  • 初始化应用main() 函数调用 runApp 启动应用。
  • 配置主题:在 MaterialApp 中配置了全局主题,包括颜色方案 (ColorScheme) 和输入框默认样式 (InputDecorationTheme)。
  • 指定首页:将 home 设置为 SignUpFormPage

代码解析

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

class MyApp extends StatelessWidget {
  // ...
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Cool Form Demo',
      // 配置全局主题
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(
          seedColor: Colors.deepPurple, // 种子颜色
          brightness: Brightness.light,
        ),
        useMaterial3: true,
        // ... 其他主题配置
      ),
      home: const SignUpFormPage(), // 设置启动页面
    );
  }
}

3. 自定义组件详解

为了提升代码复用性和界面美观度,我们封装了两个核心组件。

3.1 CoolTextField (自定义文本输入框)

文件路径:lib/widgets/cool_text_field.dart

功能描述

一个带有动画效果的输入框。当输入框获得焦点时,边框颜色改变并出现阴影,图标颜色也会随之高亮。

核心代码逻辑
  • 状态管理:使用 _isFocused 变量跟踪输入框是否获得焦点。
  • 动画容器AnimatedContainer 负责处理边框和阴影的平滑过渡动画。
  • 焦点监听:通过 FocusNode 监听焦点变化事件。
代码片段
// 监听焦点变化
void _handleFocusChange() {
  setState(() {
    _isFocused = _focusNode.hasFocus;
  });
}

// 构建 UI
AnimatedContainer(
  duration: const Duration(milliseconds: 200), // 动画时长
  decoration: BoxDecoration(
    boxShadow: _isFocused ? [...] : [...], // 根据焦点状态改变阴影
    border: Border.all(
      color: _isFocused ? Theme.of(context).primaryColor : Colors.transparent, // 根据焦点状态改变边框颜色
    ),
  ),
  child: TextFormField(
    // ...
  ),
)
如何使用
CoolTextField(
  controller: _usernameController, // 控制器
  labelText: 'Username',           // 标签文本
  hintText: 'Enter your username', // 提示文本
  prefixIcon: Icons.person,        // 前缀图标
  validator: (value) {             // 校验逻辑
    if (value == null || value.isEmpty) return 'Required';
    return null;
  },
)
注意事项
  • 控制器与焦点节点的生命周期管理:如未传入 focusNode,组件内部会创建并在 dispose 时销毁;若传入外部 focusNode,其释放需由外部负责,避免重复释放造成异常。
  • 校验函数需返回 null 表示通过:确保 validator 在通过时返回 null,否则会持续显示错误提示。
  • 输入法相关配置:keyboardTypetextInputAction 可提升输入体验,例如邮箱使用 TextInputType.emailAddress 并设置 TextInputAction.next
  • 装饰与主题交互:组件内部使用 InputBorder.none,并通过外层容器的 borderboxShadow 控制视觉效果;与全局 InputDecorationTheme 叠加时,以组件设置为准。
  • 性能与动画频率:焦点变化会触发 setState 进而驱动 AnimatedContainer 动画,频繁焦点切换可能带来轻微性能开销,属于预期范围。
特殊逻辑说明
  • 焦点高亮联动:通过监听 FocusNodehasFocus 状态,联动边框颜色与图标颜色,形成视觉反馈。
  • 阴影与边框动态切换:在获得焦点时使用较强阴影与实线边框,失焦时弱化阴影并隐藏边框,模拟“浮起”效果。
  • 外部提交联动:通过 onFieldSubmitted 可在键盘的“完成/下一步”键触发提交或跳转,便于表单串联。

3.2 CoolButton (自定义按钮)

文件路径:lib/widgets/cool_button.dart

功能描述

一个支持点击缩放动画和加载状态的渐变色按钮。

核心代码逻辑
  • 缩放动画:使用 AnimationControllerScaleTransition 实现点击时的按下缩放效果。
  • 加载状态:通过 isLoading 属性控制显示文字还是加载圈 (CircularProgressIndicator)。
  • 手势检测GestureDetector 监听按下 (onTapDown) 和抬起 (onTapUp) 事件来触发动画。
代码片段
GestureDetector(
  onTapDown: (_) => _controller.forward(), // 按下缩小
  onTapUp: (_) => _controller.reverse(),   // 抬起恢复
  onTap: widget.isLoading ? null : widget.onPressed, // 点击回调
  child: ScaleTransition(
    scale: _scaleAnimation,
    child: AnimatedContainer(
      // 渐变背景和圆角
      decoration: BoxDecoration(
        gradient: LinearGradient(...),
        // ...
      ),
      child: widget.isLoading 
          ? CircularProgressIndicator(...) // 加载中显示进度条
          : Text(widget.text, ...),        // 正常显示文字
    ),
  ),
)
如何使用
CoolButton(
  text: 'SIGN UP',          // 按钮文字
  onPressed: _submitForm,   // 点击回调函数
  isLoading: _isLoading,    // 是否显示加载状态
)
注意事项
  • 加载态下禁用点击:当 isLoadingtrue 时,onTap 被置空以避免重复触发;业务侧仍应在提交逻辑中防抖或状态锁定,避免并发提交。
  • 父容器约束:按钮使用 width: double.infinity,需要处于有宽度约束的布局(如 Column + 外层 Padding),否则可能无法正确铺满。
  • 动画控制器生命周期:组件使用 SingleTickerProviderStateMixin,确保在 dispose 中释放 AnimationController,避免内存泄漏。
  • 渐变与阴影动态:加载态时采用灰色渐变与弱阴影,常态采用主题色渐变与较强阴影,注意不同主题下的可读性与对比度。
特殊逻辑说明
  • 点击缩放反馈:通过 onTapDown/onTapUp/onTapCancel 驱动缩放动画,形成更“可点击”的触感反馈。
  • 文本与进度切换:根据 isLoading 动态切换 TextCircularProgressIndicator,确保异步过程有明确的界面状态。
  • 主题色联动:渐变依据 Theme.of(context).primaryColor 生成,随主题变更自动适配。

文件路径:lib/pages/signup_form_page.dart

这是应用的主体页面,整合了上述组件,实现了完整的注册流程。

核心功能

  1. 入场动画:使用 FadeTransition (透明度) 和 SlideTransition (位移) 让表单内容优雅地显示。
  2. 表单校验:使用 FormGlobalKey<FormState> 管理表单状态和校验逻辑。
  3. 交互反馈:点击注册后显示加载动画,成功后显示 SnackBar 提示。

关键代码解释

入场动画配置 (initState)
_animationController = AnimationController(
  vsync: this,
  duration: const Duration(milliseconds: 1200),
);

// 透明度渐变 0 -> 1
_fadeAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(...);

// 位移浮动 底部 -> 原位
_slideAnimation = Tween<Offset>(
  begin: const Offset(0, 0.5),
  end: Offset.zero,
).animate(...);

_animationController.forward(); // 启动动画
表单提交逻辑
Future<void> _submitForm() async {
  // 1. 触发表单校验
  if (_formKey.currentState!.validate()) {
    // 2. 显示加载状态
    setState(() { _isLoading = true; });

    // 3. 模拟网络请求
    await Future.delayed(const Duration(seconds: 2));

    // 4. 恢复状态并提示成功
    if (mounted) {
      setState(() { _isLoading = false; });
      ScaffoldMessenger.of(context).showSnackBar(...);
    }
  }
}
注意事项
  • 控制器释放与动画释放:页面在 dispose 中释放 TextEditingControllerAnimationController,避免内存泄漏。
  • mounted 校验:异步任务完成后通过 mounted 判断页面是否仍在树中,防止在已销毁的上下文中调用 setState
  • 表单校验与错误提示:GlobalKey<FormState> 驱动整表单校验,validator 返回字符串时显示错误;确保每个字段的校验逻辑明确且返回 null 表示通过。
  • 输入法与提交体验:为最后一个字段设置 textInputAction: TextInputAction.done 并在 onFieldSubmitted 触发 _submitForm(),提升键盘操作流畅度。
特殊逻辑说明
  • 组合入场动画:FadeTransition + SlideTransitionInterval 方式分段曲线,营造柔和入场效果,避免生硬的突然出现。
  • 主题与装饰分层:页面主题通过 InputDecorationTheme 设定基础风格,组件层的容器与图标颜色再做强调,形成清晰的层次。
  • 简易请求模拟:通过 Future.delayed 模拟网络过程并与按钮加载态联动,示范异步流程的最小闭环。

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

Logo

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

更多推荐