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。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/896978.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《OpenCV》——dlib(人脸应用实例)

文章目录 dlib库dlib库——人脸应用实例——表情识别dlib库——人脸应用实例——疲劳检测 dlib库 dlib库的基础用法介绍可以参考这篇文章&#xff1a;https://blog.csdn.net/lou0720/article/details/145968062?spm1011.2415.3001.5331&#xff0c;故此这篇文章只介绍dlib的人…

学习日记-250305

阅读论文&#xff1a;Leveraging Pedagogical Theories to Understand Student Learning Process with Graph-based Reasonable Knowledge Tracing ps:代码逻辑最后一点还没理顺&#xff0c;明天继续 4.2 Knowledge Memory & Knowledge Tracing 代码研究&#xff1a; 一般…

【AI大模型】DeepSeek + Kimi 高效制作PPT实战详解

目录 一、前言 二、传统 PPT 制作问题 2.1 传统方式制作 PPT 2.2 AI 大模型辅助制作 PPT 2.3 适用场景对比分析 2.4 最佳实践与推荐 三、DeepSeek Kimi 高效制作PPT操作实践 3.1 Kimi 简介 3.2 DeepSeek Kimi 制作PPT优势 3.2.1 DeepSeek 优势 3.2.2 Kimi 制作PPT优…

【ESP-ADF】在 VSCode 安装 ESP-ADF 注意事项

1.检查网络 如果您在中国大陆安装&#xff0c;请使用魔法上网&#xff0c;避免无法 clone ESP-ADF 仓库。 2.VSCode 安装 ESP-ADF 在 VSCode 左侧活动栏选择 ESP-IDF:explorer&#xff0c;展开 advanced 并点击 Install ESP-ADF 然后会出现选择 ESP-ADF 安装目录。 如果出现…

关于2023新版PyCharm的使用

考虑到大家AI编程的需要&#xff0c;建议大家安装新版Python解释器和新版PyCharm&#xff0c;下载地址都可以官网进行&#xff1a; Python&#xff1a;Download Python | Python.org&#xff08;可以根据需要自行选择&#xff0c;建议选择3.11&#xff0c;保持交流版本一致&am…

轻松部署 Stable Diffusion WebUI 并实现局域网共享访问:解决 Conda Python 版本不为 3.10.6 的难题

这篇博文主要为大家讲解关于sd webui的部署问题&#xff0c;大家有什么不懂的可以随时问我&#xff0c;如果没有及时回复&#xff0c;可联系&#xff1a;1198965922 如果后续大家需要了解怎么用代码调用部署好的webui的接口&#xff0c;可以在评论区留言哦&#xff0c;博主可以…

Leetcode 103: 二叉树的锯齿形层序遍历

Leetcode 103: 二叉树的锯齿形层序遍历 问题描述&#xff1a; 给定一个二叉树&#xff0c;返回其节点值的锯齿形层序遍历&#xff08;即第一层从左到右&#xff0c;第二层从右到左&#xff0c;第三层从左到右&#xff0c;依此类推&#xff09;。 适合面试的解法&#xff1a;广…

Linux中的进程间通信的方式及其使用场景

在 Linux 系统中&#xff0c;进程间通信&#xff08;Inter-Process Communication, IPC&#xff09;是指不同进程之间传递数据、共享信息的机制。Linux 提供了多种进程间通信的方式&#xff0c;每种方式都有不同的特点和使用场景。以下是常见的几种进程间通信方式及其应用场景&…

springBoot集成emqx 实现mqtt消息的发送订阅

介绍 我们可以想象这么一个场景&#xff0c;我们java应用想要采集到电表a的每小时的用电信息&#xff0c;我们怎么拿到电表的数据&#xff1f;一般我们会想 直接 java 后台发送请求给电表&#xff0c;然后让电表返回数据就可以了&#xff0c;事实上&#xff0c;我们java应用发…

vue Table 表格自适应窗口高度,表头固定

当表格内纵向内容过多时&#xff0c;可选择固定表头。 代码很简单&#xff0c;其实就是在table 里面定一个 height 属性即可。 <template><el-table:data"tableData"height"250"borderstyle"width: 100%"><el-table-columnprop…

多线程-JUC

简介 juc&#xff0c;java.util.concurrent包的简称&#xff0c;java1.5时引入。juc中提供了一系列的工具&#xff0c;可以更好地支持高并发任务 juc中提供的工具 可重入锁 ReentrantLock 可重入锁&#xff1a;ReentrantLock&#xff0c;可重入是指当一个线程获取到锁之后&…

【每日学点HarmonyOS Next知识】Web Header更新、状态变量嵌套问题、自定义弹窗、stack圆角、Flex换行问题

【每日学点HarmonyOS Next知识】Web Header更新、状态变量嵌套问题、自定义弹窗、stack圆角、Flex换行问题 1、HarmonyOS 有关webview Header无法更新的问题&#xff1f; 业务A页面 打开 webivew B页面&#xff0c;第一次打开带了header请求&#xff0c;然后退出webview B页面…

【ATXServer2】Android无法正确显示手机屏幕

文章目录 现象原因分析与解决排查手机内部minicap 解决minicap问题查看移动端Android SDK版本查看minicap支持版本单次方案多次方案 最后问题-如何支持Android SDK 32 现象 原因分析与解决 由于atxserver2在与Android动终端的链接过程中使用了agent&#xff1a;atxserver2-and…

【前端跨域】CORS:跨域资源共享的机制与实现

在现代Web开发中&#xff0c;跨域资源共享&#xff08;Cross-Origin Resource Sharing&#xff0c;简称CORS&#xff09;是一种非常重要的技术&#xff0c;用于解决浏览器跨域请求的限制 CORS允许服务器明确指定哪些外部源可以访问其资源&#xff0c;从而在保证安全的前提下实…

【设计模式】单例模式|饿汉模式|懒汉模式|指令重排序

目录 1.什么是单例模式&#xff1f; 2.如何保证单例&#xff1f; 3.两种写法 &#xff08;1&#xff09;饿汉模式&#xff08;早创建&#xff09; &#xff08;2&#xff09;懒汉模式&#xff08;缓执行&#xff0c;可能不执行&#xff09; 4.应用场景 &#x1f525;5.多…

RocketMQ顺序消费机制

RocketMQ的顺序消费机制通过生产端和消费端的协同设计实现&#xff0c;其核心在于局部顺序性&#xff0c;即保证同一队列&#xff08;MessageQueue&#xff09;内的消息严格按发送顺序消费。以下是详细机制解析及关键源码实现&#xff1a; 一、顺序消费的核心机制 1. 生产端路…

【JavaEE】-- 多线程(初阶)4

文章目录 8.多线程案例8.1 单例模式8.1.1 饿汉模式8.1.2 懒汉模式 8.2 阻塞队列8.2.1 什么是阻塞队列8.2.2 生产者消费者模型8.2.3 标准库中的阻塞队列8.2.4 阻塞队列的应用场景8.2.4.1 消息队列 8.2.5 异步操作8.2.5 自定义实现阻塞队列8.2.6 阻塞队列--生产者消费者模型 8.3 …

【C++设计模式】第四篇:建造者模式(Builder)

注意&#xff1a;复现代码时&#xff0c;确保 VS2022 使用 C17/20 标准以支持现代特性。 分步骤构造复杂对象&#xff0c;实现灵活装配 1. 模式定义与用途 核心目标&#xff1a;将复杂对象的构建过程分离&#xff0c;使得同样的构建步骤可以创建不同的表示形式。 常见场景&am…

vuex中的state是响应式的吗?

在 Vue.js 中&#xff0c;Vuex 的 state 是响应式的。这意味着当你更改 state 中的数据时&#xff0c;依赖于这些数据的 Vue 组件会自动更新。这是通过 Vue 的响应式系统实现的&#xff0c;该系统使用了 ES6 的 Proxy 对象来监听数据的变化。 当你在 Vuex 中定义了一个 state …

若依框架中的岗位与角色详解

若依框架中的岗位与角色详解 一、核心概念与定位 岗位&#xff08;Post&#xff09; 业务职能导向&#xff1a;岗位是用户在组织架构中的职务标识&#xff08;如“开发人员”“项目经理”&#xff09;&#xff0c;用于描述工作职责而非直接控制权限。岗位与部门关联&#xff…