欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > Flutter 学习之旅 之 flutter 不使用插件,简单实现一个 Toast 功能

Flutter 学习之旅 之 flutter 不使用插件,简单实现一个 Toast 功能

2025/7/17 7:24:18 来源:https://blog.csdn.net/u014361280/article/details/146050938  浏览:    关键词:Flutter 学习之旅 之 flutter 不使用插件,简单实现一个 Toast 功能

Flutter 学习之旅 之 flutter 不使用插件,简单实现一个 Toast 功能

目录

Flutter 学习之旅 之 flutter 不使用插件,简单实现一个 Toast 功能

一、简单介绍

二、简单介绍 Toast

1. 确保正确配置 navigatorKey

2. 避免重复显示 Toast

3. 确保 Toast 的上下文正确

4. 注意 Toast 的显示时长

三、简单案例实现

四、关键代码


一、简单介绍

Flutter 是一款开源的 UI 软件开发工具包,由 Google 开发和维护。它允许开发者使用一套代码同时构建跨平台的应用程序,包括移动设备(iOS 和 Android)、Web 和桌面平台(Windows、macOS 和 Linux)。

Flutter 使用 Dart 编程语言,它可以将代码编译为 ARM 或 Intel 机器代码以及 JavaScript,从而实现快速的性能。Flutter 提供了一个丰富的预置小部件库,开发者可以根据自己的需求灵活地控制每个像素,从而创建自定义的、适应性强的设计,这些设计在任何屏幕上都能呈现出色的外观和感觉。

二、简单介绍 Toast

在 Flutter 中,不使用 Toast 插件,可以通过 OverlayTimer 实现简单 Toast 功能。创建一个透明的 OverlayEntry,在其上显示自定义文本,设置显示时长后自动隐藏。这种方式无需额外依赖,灵活且轻量,适用于快速提示信息。

需要注意以下几点:


1. 确保正确配置 navigatorKey

  • Toast 功能依赖于 navigatorKey 来获取 OverlayState,因此必须在 MaterialApp 中绑定 navigatorKey

    dart复制

    MaterialApp(navigatorKey: Toast.navigatorKey,...
    );
  • 如果未绑定 navigatorKeyToast.show 方法会打印错误信息,并且无法显示 Toast。


2. 避免重复显示 Toast

  • 当用户快速多次点击按钮时,可能会导致多个 Toast 同时显示。可以通过以下方式解决:

    • 在显示 Toast 时设置一个标志位,避免重复调用。

    • 或者在显示新 Toast 时,先移除已存在的 Toast。


3. 确保 Toast 的上下文正确

  • Toast.show 方法通过 Overlay 显示,因此必须在包含 MaterialApp 的上下文中调用。

  • 如果在 MaterialApp 之外调用 Toast.show,会导致 OverlayStatenull


4. 注意 Toast 的显示时长

  • 默认情况下,Toast 的显示时长为 2 秒(Duration(seconds: 2))。如果需要更长或更短的显示时间,可以通过 duration 参数自定义:

    dart复制

    Toast.show("这是一条消息", duration: Duration(seconds: 3));
  • 如果显示时长过短,用户可能无法看清内容;如果过长,可能会影响用户体验。

三、简单案例实现

1、这里使用 Android Studio 进行创建 Flutter 项目

2、创建一个 application 的 Flutter 项目

3、编写代码,进行简单 Toast 功能实现

4、在 main 中添加测试 Toast  的 代码

5、连接设备,或者 web ,运行效果如下

四、关键代码

1、toast.dart

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';// 定义 Toast 的显示位置枚举
enum ToastPosition { top, center, bottom }class Toast {// 定义一个全局的 NavigatorState 键,用于获取 OverlayStatestatic final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();// Toast 显示方法static void show(String message, {ToastPosition position = ToastPosition.bottom, // 默认显示在底部Duration duration = const Duration(seconds: 2), // 默认显示时长为 2 秒}) {// 获取当前的 OverlayStatefinal OverlayState? overlayState = navigatorKey.currentState?.overlay;// 如果 OverlayState 为空,说明未正确设置 MaterialApp 的 navigatorKeyif (overlayState == null) {print("OverlayState is null. Make sure to use MaterialApp with navigatorKey.");return;}// 创建一个 OverlayEntry,用于显示 Toastfinal OverlayEntry overlayEntry = OverlayEntry(builder: (context) {// 根据 position 参数设置 Toast 的对齐方式return Align(alignment: position == ToastPosition.center? Alignment.center // 显示在屏幕中央: position == ToastPosition.top? Alignment.topCenter // 显示在顶部: Alignment.bottomCenter, // 显示在底部child: Padding(padding: EdgeInsets.only(top: position == ToastPosition.top ? 20 : 0, // 距离顶部 20pxbottom: position == ToastPosition.bottom ? 20 : 0, // 距离底部 20px),child: Material(elevation: 4, // 添加阴影效果borderRadius: BorderRadius.circular(50), // 设置为半圆形状child: Container(constraints: BoxConstraints(minWidth: 100, maxWidth: 300), // 限制 Toast 的宽度padding: EdgeInsets.all(16), // 内边距decoration: BoxDecoration(color: Colors.black87, // 背景颜色borderRadius: BorderRadius.circular(50), // 设置为半圆形状),child: Text(message, // 显示的文本内容style: TextStyle(color: Colors.white, fontSize: 16), // 文本样式textAlign: TextAlign.center, // 文本居中softWrap: true, // 自动换行maxLines: null, // 不限制行数),),),),);},);// 将 OverlayEntry 插入到 Overlay 中,显示 ToastoverlayState.insert(overlayEntry);// 使用 SchedulerBinding 添加一个后帧回调SchedulerBinding.instance.addPostFrameCallback((_) {// 在指定的 duration 时间后移除 OverlayEntry,隐藏 ToastFuture.delayed(duration).then((_) {overlayEntry.remove();});});}
}

代码说明:

  1. ToastPosition 枚举:定义了 Toast 的显示位置(顶部、中央、底部)。

  2. navigatorKey:用于获取当前 MaterialAppNavigatorState,从而获取 OverlayState

  3. show 方法

    • 接收 message 参数(显示的文本)和可选参数(位置和显示时长)。

    • 检查 OverlayState 是否为空,确保 MaterialApp 已正确配置。

    • 创建 OverlayEntry 并根据位置参数设置对齐方式。

    • 使用 MaterialContainer 构造 Toast 的样式,包括背景颜色、阴影、圆角和文本样式。

    • OverlayEntry 插入到 Overlay 中,显示 Toast。

    • 使用 SchedulerBindingFuture.delayed 在指定时长后移除 Toast。

2、main.dart

import 'package:flutter/material.dart';
import 'toast.dart'; // 导入封装的 Toast 工具类,用于显示自定义 Toastvoid main() {runApp(MyApp());
}class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {return MaterialApp(title: 'Flutter Toast Demo', // 应用的标题navigatorKey: Toast.navigatorKey, // 将全局的 navigatorKey 绑定到 MaterialApphome: Scaffold( // 主页面布局appBar: AppBar( // 应用栏title: Text('Flutter Toast Demo'), // 标题),body: Center( // 主体内容居中child: Column( // 垂直布局mainAxisAlignment: MainAxisAlignment.center, // 子组件垂直居中children: [ElevatedButton( // 按钮,点击后显示顶部 ToastonPressed: () {Toast.show("这是一条顶部 Toast辅导费地方东方饭店", // 要显示的文本position: ToastPosition.top, // 设置 Toast 显示在顶部);},child: Text('显示顶部 Toast'), // 按钮文本),SizedBox(height: 20), // 间距ElevatedButton( // 按钮,点击后显示中间 ToastonPressed: () {Toast.show("这是一条中间 Toast", // 要显示的文本position: ToastPosition.center, // 设置 Toast 显示在中间);},child: Text('显示中间 Toast'), // 按钮文本),SizedBox(height: 20), // 间距ElevatedButton( // 按钮,点击后显示底部 ToastonPressed: () {Toast.show("这是一条底部 Toast", // 要显示的文本position: ToastPosition.bottom, // 设置 Toast 显示在底部);},child: Text('显示底部 Toast'), // 按钮文本),],),),),);}
}

代码说明:

  1. 导入模块

    • import 'toast.dart';:导入封装好的 Toast 工具类,用于实现自定义 Toast 功能。

  2. MyApp

    • MaterialApp:Flutter 的根组件,用于配置主题和路由。

    • navigatorKey: Toast.navigatorKey:将 Toast 类中定义的全局 navigatorKey 绑定到 MaterialApp,以便通过 navigatorKey 获取 OverlayState,这是显示 Toast 的关键。

  3. Scaffold

    • Scaffold 是 Flutter 中用于构建页面布局的基础组件,包含 appBarbody

    • appBar:显示页面的标题。

    • body:页面的主体内容,使用 CenterColumn 布局,将按钮垂直居中。

  4. 按钮功能

    • 每个按钮通过 onPressed 回调调用 Toast.show 方法。

    • Toast.show 方法接收一个字符串(要显示的文本)和一个可选参数 position(指定 Toast 的显示位置:顶部、中间、底部)。

    • 示例中分别展示了如何调用顶部、中间和底部的 Toast。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词