当前位置: 首页 > article >正文

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 键,用于获取 OverlayState
  static final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

  // Toast 显示方法
  static void show(
      String message, {
        ToastPosition position = ToastPosition.bottom, // 默认显示在底部
        Duration duration = const Duration(seconds: 2), // 默认显示时长为 2 秒
      }) {
    // 获取当前的 OverlayState
    final OverlayState? overlayState = navigatorKey.currentState?.overlay;

    // 如果 OverlayState 为空,说明未正确设置 MaterialApp 的 navigatorKey
    if (overlayState == null) {
      print("OverlayState is null. Make sure to use MaterialApp with navigatorKey.");
      return;
    }

    // 创建一个 OverlayEntry,用于显示 Toast
    final 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, // 距离顶部 20px
              bottom: 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 中,显示 Toast
    overlayState.insert(overlayEntry);

    // 使用 SchedulerBinding 添加一个后帧回调
    SchedulerBinding.instance.addPostFrameCallback((_) {
      // 在指定的 duration 时间后移除 OverlayEntry,隐藏 Toast
      Future.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 工具类,用于显示自定义 Toast

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Toast Demo', // 应用的标题
      navigatorKey: Toast.navigatorKey, // 将全局的 navigatorKey 绑定到 MaterialApp
      home: Scaffold( // 主页面布局
        appBar: AppBar( // 应用栏
          title: Text('Flutter Toast Demo'), // 标题
        ),
        body: Center( // 主体内容居中
          child: Column( // 垂直布局
            mainAxisAlignment: MainAxisAlignment.center, // 子组件垂直居中
            children: [
              ElevatedButton( // 按钮,点击后显示顶部 Toast
                onPressed: () {
                  Toast.show(
                    "这是一条顶部 Toast辅导费地方东方饭店", // 要显示的文本
                    position: ToastPosition.top, // 设置 Toast 显示在顶部
                  );
                },
                child: Text('显示顶部 Toast'), // 按钮文本
              ),
              SizedBox(height: 20), // 间距
              ElevatedButton( // 按钮,点击后显示中间 Toast
                onPressed: () {
                  Toast.show(
                    "这是一条中间 Toast", // 要显示的文本
                    position: ToastPosition.center, // 设置 Toast 显示在中间
                  );
                },
                child: Text('显示中间 Toast'), // 按钮文本
              ),
              SizedBox(height: 20), // 间距
              ElevatedButton( // 按钮,点击后显示底部 Toast
                onPressed: () {
                  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.kler.cn/a/579183.html

相关文章:

  • Web3 的未来:去中心化如何重塑互联网
  • 03.05 QT事件
  • uniapp uniCloud引发的血案(switchTab: Missing required args: “url“)!!!!!!!!!!
  • 力扣72题编辑距离
  • Linux运维——oh-my-zsh
  • 高效处理 List<T> 集合:更新、查找与优化技巧
  • 《A++ 敏捷开发》- 18 软件需求
  • HTML 文本格式化
  • Python爬取咸鱼Goodfish店铺所有商品接口的详细指南
  • Android中的Fragment是什么以及它有哪些生命周期方法
  • unity学习64,第3个小游戏:一个2D跑酷游戏
  • react基本功
  • 【漫话机器学习系列】121.偏导数(Partial Derivative)
  • 【springcloud】快速搭建一套分布式服务springcloudalibaba(二)
  • 前端常用布局
  • Deeplabv3+改进4:在主干网络中添加GAMAattention|助力涨点!
  • Python实现鼠标点击获取窗口进程信息
  • Android FragmentContainerView如何使用
  • Oracle 字符类型对比
  • Manus AI Agent 技术解读:架构、机制与竞品对比