Flutter 學習之旅 之 flutter 不使用插件,簡單實現一個 Toast 功能
目錄
Flutter 學習之旅 之 flutter 不使用插件,簡單實現一個 Toast 功能
一、簡單介紹
二、簡單介紹 Toast
2. 避免重復顯示 Toast
3. 確保 Toast 的上下文正確
4. 注意 Toast 的顯示時長
三、簡單案例實現
四、關鍵代碼
一、簡單介紹
Flutter 是一款開源的 UI 軟件開發工具包,由 Google 開發和維護。它允許開發者使用一套代碼同時構建跨平臺的應用程序,包括移動設備(iOS 和 Android)、Web 和桌面平臺(Windows、macOS 和 Linux)。
Flutter 使用 Dart 編程語言,它可以將代碼編譯為 ARM 或 Intel 機器代碼以及 JavaScript,從而實現快速的性能。Flutter 提供了一個豐富的預置小部件庫,開發者可以根據自己的需求靈活地控制每個像素,從而創建自定義的、適應性強的設計,這些設計在任何屏幕上都能呈現出色的外觀和感覺。
二、簡單介紹 Toast
在 Flutter 中,不使用 Toast 插件,可以通過 Overlay
和 Timer
實現簡單 Toast 功能。創建一個透明的 OverlayEntry
,在其上顯示自定義文本,設置顯示時長后自動隱藏。這種方式無需額外依賴,靈活且輕量,適用于快速提示信息。
需要注意以下幾點:
1. 確保正確配置 navigatorKey
-
Toast
功能依賴于navigatorKey
來獲取OverlayState
,因此必須在MaterialApp
中綁定navigatorKey
:dart復制
MaterialApp(navigatorKey: Toast.navigatorKey,... );
-
如果未綁定
navigatorKey
,Toast.show
方法會打印錯誤信息,并且無法顯示 Toast。
2. 避免重復顯示 Toast
-
當用戶快速多次點擊按鈕時,可能會導致多個 Toast 同時顯示。可以通過以下方式解決:
-
在顯示 Toast 時設置一個標志位,避免重復調用。
-
或者在顯示新 Toast 時,先移除已存在的 Toast。
-
3. 確保 Toast 的上下文正確
-
Toast.show
方法通過Overlay
顯示,因此必須在包含MaterialApp
的上下文中調用。 -
如果在
MaterialApp
之外調用Toast.show
,會導致OverlayState
為null
。
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();});});}
}
代碼說明:
ToastPosition
枚舉:定義了 Toast 的顯示位置(頂部、中央、底部)。
navigatorKey
:用于獲取當前MaterialApp
的NavigatorState
,從而獲取OverlayState
。
show
方法:
接收
message
參數(顯示的文本)和可選參數(位置和顯示時長)。檢查
OverlayState
是否為空,確保MaterialApp
已正確配置。創建
OverlayEntry
并根據位置參數設置對齊方式。使用
Material
和Container
構造 Toast 的樣式,包括背景顏色、陰影、圓角和文本樣式。將
OverlayEntry
插入到Overlay
中,顯示 Toast。使用
SchedulerBinding
和Future.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'), // 按鈕文本),],),),),);}
}
代碼說明:
導入模塊:
import 'toast.dart';
:導入封裝好的 Toast 工具類,用于實現自定義 Toast 功能。
MyApp
類:
MaterialApp
:Flutter 的根組件,用于配置主題和路由。
navigatorKey: Toast.navigatorKey
:將Toast
類中定義的全局navigatorKey
綁定到MaterialApp
,以便通過navigatorKey
獲取OverlayState
,這是顯示 Toast 的關鍵。
Scaffold
:
Scaffold
是 Flutter 中用于構建頁面布局的基礎組件,包含appBar
和body
。
appBar
:顯示頁面的標題。
body
:頁面的主體內容,使用Center
和Column
布局,將按鈕垂直居中。按鈕功能:
每個按鈕通過
onPressed
回調調用Toast.show
方法。
Toast.show
方法接收一個字符串(要顯示的文本)和一個可選參數position
(指定 Toast 的顯示位置:頂部、中間、底部)。示例中分別展示了如何調用頂部、中間和底部的 Toast。