基础入门 Flutter for OpenHarmony:fluttertoast 消息提示详解

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
🎯 欢迎来到 Flutter for OpenHarmony 社区!本文将深入讲解 Flutter 中 fluttertoast 消息提示组件的使用方法,带你全面掌握在应用中显示 Toast 提示的各种技巧。


一、fluttertoast 组件概述

在 Flutter for OpenHarmony 应用开发中,fluttertoast 是一个非常实用的消息提示插件,用于在应用中显示简短的 Toast 提示信息。Toast 是一种轻量级的反馈机制,它会在屏幕上短暂显示一条消息,然后自动消失,不会打断用户的操作流程。

📋 fluttertoast 组件特点

特点 说明
跨平台支持 支持 Android、iOS、Web、OpenHarmony
轻量级 不需要上下文,可在任何地方调用
自定义样式 支持自定义背景色、文字颜色、位置、时长等
非阻塞式 Toast 显示不会阻塞用户操作
自动消失 Toast 会在显示一段时间后自动消失
简单易用 API 简洁直观,一行代码即可显示 Toast

💡 使用场景:操作成功提示、错误信息提示、网络状态提示、表单验证反馈、复制成功提示等轻量级消息通知。


二、OpenHarmony 平台适配说明

2.1 兼容性信息

本项目基于 fluttertoast@8.2.8 开发,适配 Flutter 3.27.5-ohos-1.0.4。

2.2 支持的功能

在 OpenHarmony 平台上,fluttertoast 支持以下功能:

功能 说明 OpenHarmony 支持
showToast() 显示 Toast 消息 ✅ yes
cancel() 取消当前显示的 Toast ✅ yes
自定义背景色 设置 Toast 背景颜色 ✅ yes
自定义文字颜色 设置 Toast 文字颜色 ✅ yes
自定义位置 设置 Toast 显示位置 ✅ yes
自定义时长 设置 Toast 显示时长 ✅ yes

三、项目配置与安装

3.1 添加依赖配置

首先,需要在你的 Flutter 项目的 pubspec.yaml 文件中添加 fluttertoast 依赖。

打开项目根目录下的 pubspec.yaml 文件,找到 dependencies 部分,添加以下配置:

yaml 复制代码
dependencies:
  flutter:
    sdk: flutter

  # 添加 fluttertoast 依赖(OpenHarmony 适配版本)
  fluttertoast:
    git:
      url: "https://atomgit.com/openharmony-sig/flutter_fluttertoast.git"
      ref: "br_8.2.8_ohos"

配置说明:

  • 使用 git 方式引用开源鸿蒙适配的 flutter_fluttertoast 仓库
  • url:指定 AtomGit 托管的仓库地址
  • ref:指定适配 OpenHarmony 的分支版本
  • 本项目基于 fluttertoast@8.2.8 开发,适配 Flutter 3.27.5-ohos-1.0.4

⚠️ 重要:对于 OpenHarmony 平台,必须使用 git 方式引用适配版本,不能直接使用 pub.dev 的版本号。

3.2 下载依赖

配置完成后,需要在项目根目录执行以下命令下载依赖:

bash 复制代码
flutter pub get

执行成功后,你会看到类似以下的输出:

复制代码
Running "flutter pub get" in my_cross_platform_app...
Resolving dependencies...
Got dependencies!

3.3 依赖自动配置说明

执行 flutter pub get 后,OpenHarmony 平台的依赖会自动配置到 ohos/entry/oh-package.json5 文件中。Flutter 构建系统会自动处理平台相关的依赖配置,无需手动干预。


四、fluttertoast 基础用法

4.1 导入库

在使用 fluttertoast 之前,需要先导入库:

dart 复制代码
import 'package:fluttertoast/fluttertoast.dart';

4.2 显示简单 Toast

最简单的 Toast 调用方式:

dart 复制代码
Fluttertoast.showToast(
  msg: "这是一条 Toast 消息",
);

4.3 自定义 Toast 样式

fluttertoast 提供了丰富的自定义选项:

dart 复制代码
Fluttertoast.showToast(
  msg: "操作成功!",
  toastLength: Toast.LENGTH_SHORT,
  gravity: ToastGravity.BOTTOM,
  timeInSecForIosWeb: 1,
  backgroundColor: Colors.green,
  textColor: Colors.white,
  fontSize: 16.0,
);

4.4 Toast 位置设置

Toast 可以显示在屏幕的不同位置:

dart 复制代码
// 底部显示(默认)
Fluttertoast.showToast(
  msg: "底部 Toast",
  gravity: ToastGravity.BOTTOM,
);

// 居中显示
Fluttertoast.showToast(
  msg: "居中 Toast",
  gravity: ToastGravity.CENTER,
);

// 顶部显示
Fluttertoast.showToast(
  msg: "顶部 Toast",
  gravity: ToastGravity.TOP,
);

4.5 Toast 时长设置

Toast 支持两种显示时长:

dart 复制代码
// 短时间显示(约 2 秒)
Fluttertoast.showToast(
  msg: "短时间 Toast",
  toastLength: Toast.LENGTH_SHORT,
);

// 长时间显示(约 3.5 秒)
Fluttertoast.showToast(
  msg: "长时间 Toast",
  toastLength: Toast.LENGTH_LONG,
);

五、常用 API 详解

5.1 showToast - 显示 Toast

显示 Toast 消息的主要方法:

dart 复制代码
Fluttertoast.showToast({
  required String msg,              // 必填:Toast 消息内容
  Toast? toastLength,               // 显示时长:LENGTH_SHORT 或 LENGTH_LONG
  int? timeInSecForIosWeb,          // iOS/Web 平台的显示秒数
  double? fontSize,                 // 文字大小
  ToastGravity? gravity,            // 显示位置
  Color? backgroundColor,           // 背景颜色
  Color? textColor,                 // 文字颜色
});

参数说明:

参数 类型 默认值 说明
msg String 必填 Toast 显示的消息内容
toastLength Toast LENGTH_SHORT Toast 显示时长
timeInSecForIosWeb int 1 iOS/Web 平台显示秒数
fontSize double 16.0 文字大小
gravity ToastGravity BOTTOM Toast 显示位置
backgroundColor Color Colors.black87 背景颜色
textColor Color Colors.white 文字颜色

5.2 cancel - 取消 Toast

取消当前正在显示的 Toast:

dart 复制代码
Fluttertoast.cancel();

使用场景:

  • 页面退出时取消 Toast
  • 显示新的 Toast 前取消旧的 Toast
  • 用户主动关闭 Toast

5.3 ToastGravity - 位置枚举

Toast 显示位置的枚举值:

枚举值 说明
ToastGravity.TOP 屏幕顶部显示
ToastGravity.CENTER 屏幕居中显示
ToastGravity.BOTTOM 屏幕底部显示

5.4 Toast - 时长枚举

Toast 显示时长的枚举值:

枚举值 说明
Toast.LENGTH_SHORT 短时间显示
Toast.LENGTH_LONG 长时间显示

六、实际应用场景

6.1 操作成功提示

dart 复制代码
class SuccessToastExample extends StatelessWidget {
  const SuccessToastExample({super.key});

  void _showSuccessToast() {
    Fluttertoast.showToast(
      msg: "保存成功!",
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
      backgroundColor: Colors.green,
      textColor: Colors.white,
      fontSize: 16.0,
    );
  }

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: _showSuccessToast,
      child: const Text('保存'),
    );
  }
}

6.2 错误提示

dart 复制代码
class ErrorToastExample extends StatelessWidget {
  const ErrorToastExample({super.key});

  void _showErrorToast(String message) {
    Fluttertoast.showToast(
      msg: message,
      toastLength: Toast.LENGTH_LONG,
      gravity: ToastGravity.CENTER,
      backgroundColor: Colors.red,
      textColor: Colors.white,
      fontSize: 16.0,
    );
  }

  Future<void> _submitForm() async {
    try {
      // 提交表单逻辑
      await Future.delayed(const Duration(seconds: 1));
      Fluttertoast.showToast(
        msg: "提交成功!",
        backgroundColor: Colors.green,
        textColor: Colors.white,
      );
    } catch (e) {
      _showErrorToast("提交失败:$e");
    }
  }

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: _submitForm,
      child: const Text('提交'),
    );
  }
}

6.3 网络状态提示

dart 复制代码
class NetworkToastExample {
  void showNetworkError() {
    Fluttertoast.showToast(
      msg: "网络连接失败,请检查网络设置",
      toastLength: Toast.LENGTH_LONG,
      gravity: ToastGravity.BOTTOM,
      backgroundColor: Colors.orange,
      textColor: Colors.white,
    );
  }

  void showNetworkRestored() {
    Fluttertoast.showToast(
      msg: "网络已恢复",
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.BOTTOM,
      backgroundColor: Colors.blue,
      textColor: Colors.white,
    );
  }
}

6.4 表单验证提示

dart 复制代码
class FormValidationExample extends StatefulWidget {
  const FormValidationExample({super.key});

  @override
  State<FormValidationExample> createState() => _FormValidationExampleState();
}

class _FormValidationExampleState extends State<FormValidationExample> {
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();

  bool _validateForm() {
    if (_emailController.text.isEmpty) {
      Fluttertoast.showToast(
        msg: "请输入邮箱地址",
        backgroundColor: Colors.orange,
        textColor: Colors.white,
      );
      return false;
    }

    if (!_emailController.text.contains('@')) {
      Fluttertoast.showToast(
        msg: "请输入有效的邮箱地址",
        backgroundColor: Colors.orange,
        textColor: Colors.white,
      );
      return false;
    }

    if (_passwordController.text.length < 6) {
      Fluttertoast.showToast(
        msg: "密码长度不能少于6位",
        backgroundColor: Colors.orange,
        textColor: Colors.white,
      );
      return false;
    }

    return true;
  }

  void _submit() {
    if (_validateForm()) {
      Fluttertoast.showToast(
        msg: "登录成功!",
        backgroundColor: Colors.green,
        textColor: Colors.white,
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        TextField(
          controller: _emailController,
          decoration: const InputDecoration(labelText: '邮箱'),
        ),
        TextField(
          controller: _passwordController,
          decoration: const InputDecoration(labelText: '密码'),
          obscureText: true,
        ),
        const SizedBox(height: 16),
        ElevatedButton(
          onPressed: _submit,
          child: const Text('登录'),
        ),
      ],
    );
  }
}

6.5 复制成功提示

dart 复制代码
import 'package:flutter/services.dart';

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

  Future<void> _copyToClipboard(String text) async {
    await Clipboard.setData(ClipboardData(text: text));
    Fluttertoast.showToast(
      msg: "已复制到剪贴板",
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
      backgroundColor: Colors.grey[800],
      textColor: Colors.white,
    );
  }

  @override
  Widget build(BuildContext context) {
    return IconButton(
      icon: const Icon(Icons.copy),
      onPressed: () => _copyToClipboard("复制的内容"),
    );
  }
}

七、完整示例代码

下面是一个完整的示例应用,展示了 fluttertoast 的各种用法:

dart 复制代码
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Fluttertoast 示例',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF6366F1)),
        useMaterial3: true,
      ),
      home: const ToastDemoPage(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Fluttertoast 示例'),
        centerTitle: true,
        elevation: 0,
      ),
      body: Container(
        decoration: const BoxDecoration(
          gradient: LinearGradient(
            begin: Alignment.topCenter,
            end: Alignment.bottomCenter,
            colors: [
              Color(0xFFE8F4FF),
              Color(0xFFF8F9FF),
            ],
          ),
        ),
        child: SafeArea(
          child: SingleChildScrollView(
            padding: const EdgeInsets.all(20),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                _buildSectionTitle('基础 Toast'),
                const SizedBox(height: 12),
                _buildButton('显示简单 Toast', () {
                  Fluttertoast.showToast(msg: "这是一条简单的 Toast 消息");
                }),
                const SizedBox(height: 12),
                _buildSectionTitle('位置设置'),
                const SizedBox(height: 12),
                Row(
                  children: [
                    Expanded(
                      child: _buildButton('顶部', () {
                        Fluttertoast.showToast(
                          msg: "顶部 Toast",
                          gravity: ToastGravity.TOP,
                          backgroundColor: Colors.blue,
                        );
                      }),
                    ),
                    const SizedBox(width: 12),
                    Expanded(
                      child: _buildButton('居中', () {
                        Fluttertoast.showToast(
                          msg: "居中 Toast",
                          gravity: ToastGravity.CENTER,
                          backgroundColor: Colors.purple,
                        );
                      }),
                    ),
                    const SizedBox(width: 12),
                    Expanded(
                      child: _buildButton('底部', () {
                        Fluttertoast.showToast(
                          msg: "底部 Toast",
                          gravity: ToastGravity.BOTTOM,
                          backgroundColor: Colors.teal,
                        );
                      }),
                    ),
                  ],
                ),
                const SizedBox(height: 24),
                _buildSectionTitle('状态提示'),
                const SizedBox(height: 12),
                Row(
                  children: [
                    Expanded(
                      child: _buildButton('成功', () {
                        Fluttertoast.showToast(
                          msg: "操作成功!",
                          gravity: ToastGravity.CENTER,
                          backgroundColor: Colors.green,
                          textColor: Colors.white,
                        );
                      }, color: Colors.green),
                    ),
                    const SizedBox(width: 12),
                    Expanded(
                      child: _buildButton('错误', () {
                        Fluttertoast.showToast(
                          msg: "操作失败!",
                          gravity: ToastGravity.CENTER,
                          backgroundColor: Colors.red,
                          textColor: Colors.white,
                        );
                      }, color: Colors.red),
                    ),
                    const SizedBox(width: 12),
                    Expanded(
                      child: _buildButton('警告', () {
                        Fluttertoast.showToast(
                          msg: "请注意!",
                          gravity: ToastGravity.CENTER,
                          backgroundColor: Colors.orange,
                          textColor: Colors.white,
                        );
                      }, color: Colors.orange),
                    ),
                  ],
                ),
                const SizedBox(height: 24),
                _buildSectionTitle('时长设置'),
                const SizedBox(height: 12),
                Row(
                  children: [
                    Expanded(
                      child: _buildButton('短时间', () {
                        Fluttertoast.showToast(
                          msg: "短时间 Toast(约2秒)",
                          toastLength: Toast.LENGTH_SHORT,
                          backgroundColor: Colors.indigo,
                        );
                      }),
                    ),
                    const SizedBox(width: 12),
                    Expanded(
                      child: _buildButton('长时间', () {
                        Fluttertoast.showToast(
                          msg: "长时间 Toast(约3.5秒)",
                          toastLength: Toast.LENGTH_LONG,
                          backgroundColor: Colors.indigo,
                        );
                      }),
                    ),
                  ],
                ),
                const SizedBox(height: 24),
                _buildSectionTitle('自定义样式'),
                const SizedBox(height: 12),
                _buildButton('自定义颜色和大小', () {
                  Fluttertoast.showToast(
                    msg: "自定义样式的 Toast",
                    gravity: ToastGravity.CENTER,
                    backgroundColor: const Color(0xFF6366F1),
                    textColor: Colors.white,
                    fontSize: 18.0,
                  );
                }),
                const SizedBox(height: 12),
                _buildButton('圆角背景 Toast', () {
                  Fluttertoast.showToast(
                    msg: "  🎉 恭喜你!操作成功  ",
                    gravity: ToastGravity.CENTER,
                    backgroundColor: Colors.black87,
                    textColor: Colors.white,
                    fontSize: 16.0,
                  );
                }),
                const SizedBox(height: 24),
                _buildSectionTitle('取消 Toast'),
                const SizedBox(height: 12),
                _buildButton('取消当前 Toast', () {
                  Fluttertoast.cancel();
                  ScaffoldMessenger.of(context).showSnackBar(
                    const SnackBar(content: Text('Toast 已取消')),
                  );
                }, color: Colors.grey),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Widget _buildSectionTitle(String title) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
      decoration: BoxDecoration(
        gradient: const LinearGradient(
          colors: [Color(0xFF6366F1), Color(0xFF8B5CF6)],
        ),
        borderRadius: BorderRadius.circular(8),
      ),
      child: Text(
        title,
        style: const TextStyle(
          color: Colors.white,
          fontSize: 16,
          fontWeight: FontWeight.bold,
        ),
      ),
    );
  }

  Widget _buildButton(String text, VoidCallback onPressed, {Color? color}) {
    return ElevatedButton(
      onPressed: onPressed,
      style: ElevatedButton.styleFrom(
        backgroundColor: color ?? const Color(0xFF6366F1),
        foregroundColor: Colors.white,
        padding: const EdgeInsets.symmetric(vertical: 14),
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(12),
        ),
      ),
      child: Text(text),
    );
  }
}

八、Toast 与 SnackBar 的区别

在 Flutter 中,除了 Toast,还有 SnackBar 也可以用于显示提示信息。两者有以下区别:

特性 Toast SnackBar
上下文依赖 不需要 BuildContext 需要 ScaffoldMessenger
显示位置 可自定义(上/中/下) 固定在底部
交互能力 不支持交互 支持添加操作按钮
持续时间 固定时长 可自定义时长
隐藏方式 自动消失 可滑动关闭或手动关闭
适用场景 轻量级提示、无需交互 需要用户确认或操作的提示

选择建议:

  • 如果只需要简单的提示信息,不需要用户交互,使用 Toast
  • 如果需要用户确认或提供撤销操作,使用 SnackBar

九、常见问题与解决方案

9.1 Toast 不显示

问题原因:

  • 未正确导入库
  • 在 initState 中调用(Widget 未构建完成)

解决方案:

dart 复制代码
// 错误示例
@override
void initState() {
  super.initState();
  Fluttertoast.showToast(msg: "初始化提示");  // 可能不显示
}

// 正确示例
@override
void initState() {
  super.initState();
  WidgetsBinding.instance.addPostFrameCallback((_) {
    Fluttertoast.showToast(msg: "初始化提示");
  });
}

9.2 Toast 样式不生效

问题原因:

  • 平台限制,某些样式在某些平台上可能不支持

解决方案:

  • 使用平台支持的样式属性
  • 对于复杂样式需求,考虑使用 Overlay 或自定义 Widget

9.3 Toast 重复显示

问题原因:

  • 快速点击按钮触发多次 Toast

解决方案:

dart 复制代码
DateTime? _lastToastTime;

void _showToast(String message) {
  final now = DateTime.now();
  if (_lastToastTime == null || 
      now.difference(_lastToastTime!).inMilliseconds > 2000) {
    Fluttertoast.showToast(msg: message);
    _lastToastTime = now;
  }
}

十、总结

fluttertoast 是 Flutter for OpenHarmony 应用开发中常用的消息提示组件。通过本文的学习,我们掌握了:

  1. 基础用法:显示简单 Toast 消息
  2. 自定义样式:背景色、文字颜色、位置、时长等
  3. 位置设置:顶部、居中、底部显示
  4. 时长设置:短时间和长时间显示
  5. 实际应用:成功提示、错误提示、表单验证等场景
  6. 与 SnackBar 的区别:选择合适的提示方式

💡 开发建议:使用 fluttertoast 时应注意:

  • Toast 应简洁明了,避免过长文字
  • 选择合适的显示位置和颜色
  • 避免在短时间内频繁显示 Toast
  • 重要操作提示考虑使用 SnackBar 或 Dialog
相关推荐
哈__6 小时前
基础入门 Flutter for OpenHarmony:SystemChrome 屏幕方向控制详解
flutter
键盘鼓手苏苏8 小时前
Flutter for OpenHarmony 实战:Flutter Rust Bridge — 极致计算性能方案
开发语言·后端·flutter·华为·rust·json·harmonyos
夏小鱼的blog9 小时前
【AtomGit 携手开源鸿蒙】Flutter-OH三方库鸿蒙化 - 1
flutter·开源·harmonyos
哈__9 小时前
基础入门 Flutter for OpenHarmony:webview_flutter 内嵌浏览器详解
flutter·华为·harmonyos
松叶似针9 小时前
Flutter三方库适配OpenHarmony【secure_application】— 插件功能全景与适配价值
flutter·harmonyos·鸿蒙
钛态9 小时前
Flutter for OpenHarmony:leak_tracker 自动监测内存泄漏,精准定位未释放对象(内存性能优化) 深度解析与鸿蒙适配指南
flutter·华为·性能优化·harmonyos
松叶似针9 小时前
Flutter三方库适配OpenHarmony【secure_application】— 开发环境与工具链准备
flutter·harmonyos
钛态9 小时前
Flutter for OpenHarmony:formz 简化表单验证逻辑,分离 UI 与业务状态(声明式表单验证) 深度解析与鸿蒙适配指南
flutter·ui·华为·harmonyos
不爱吃糖的程序媛10 小时前
Puro 全面解析:比 FVM 更快更省的 Flutter 版本管理器(鸿蒙定制版首选)
flutter