feat: add fluttertoast localization with HarmonyOS support and ToastService
This commit is contained in:
18
CHANGELOG.md
18
CHANGELOG.md
@@ -2,6 +2,24 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [0.8.0] - 2026-04-08
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- 📱 **fluttertoast 本地化** - 下载 fluttertoast v9.0.0 到本地 packages 目录
|
||||||
|
- 支持鸿蒙平台适配
|
||||||
|
- 创建 `fluttertoast_ohos` 适配模块
|
||||||
|
- 本地路径导入,支持自定义修改
|
||||||
|
|
||||||
|
- 🎨 **ToastService 消息服务** - 统一 Toast 消息样式
|
||||||
|
- 支持 4 种消息类型(success、error、warning、info)
|
||||||
|
- 自动适配 App 动态主题
|
||||||
|
- 集成 PageStandards 页面规范
|
||||||
|
- 提供简洁的 API 接口
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- 📦 更新 `pubspec.yaml` 使用本地 `fluttertoast`
|
||||||
|
- 🔧 更新 `fluttertoast` 支持鸿蒙平台
|
||||||
|
|
||||||
## [0.7.0] - 2026-04-08
|
## [0.7.0] - 2026-04-08
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
218
lib/src/services/toast_service.dart
Normal file
218
lib/src/services/toast_service.dart
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
|
import 'package:mom_kitchen/src/standards/page_standards.dart';
|
||||||
|
|
||||||
|
enum ToastType { success, error, warning, info }
|
||||||
|
|
||||||
|
class ToastService {
|
||||||
|
static final ToastService _instance = ToastService._internal();
|
||||||
|
factory ToastService() => _instance;
|
||||||
|
ToastService._internal();
|
||||||
|
|
||||||
|
static final FToast _fToast = FToast();
|
||||||
|
|
||||||
|
static void init(BuildContext context) {
|
||||||
|
_fToast.init(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<void> show({
|
||||||
|
required String message,
|
||||||
|
ToastType type = ToastType.info,
|
||||||
|
Duration duration = const Duration(seconds: 2),
|
||||||
|
ToastGravity gravity = ToastGravity.BOTTOM,
|
||||||
|
}) async {
|
||||||
|
final context = Get.context;
|
||||||
|
if (context == null) {
|
||||||
|
await _showNativeToast(message: message, type: type, gravity: gravity);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final standards = PageStandards.of(context);
|
||||||
|
_showCustomToast(
|
||||||
|
message: message,
|
||||||
|
type: type,
|
||||||
|
duration: duration,
|
||||||
|
gravity: gravity,
|
||||||
|
standards: standards,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<void> _showNativeToast({
|
||||||
|
required String message,
|
||||||
|
required ToastType type,
|
||||||
|
required ToastGravity gravity,
|
||||||
|
}) async {
|
||||||
|
Color backgroundColor;
|
||||||
|
switch (type) {
|
||||||
|
case ToastType.success:
|
||||||
|
backgroundColor = const Color(0xFF4CAF50);
|
||||||
|
break;
|
||||||
|
case ToastType.error:
|
||||||
|
backgroundColor = const Color(0xFFF44336);
|
||||||
|
break;
|
||||||
|
case ToastType.warning:
|
||||||
|
backgroundColor = const Color(0xFFFF9800);
|
||||||
|
break;
|
||||||
|
case ToastType.info:
|
||||||
|
backgroundColor = const Color(0xFF2196F3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
await Fluttertoast.showToast(
|
||||||
|
msg: message,
|
||||||
|
toastLength: Toast.LENGTH_SHORT,
|
||||||
|
gravity: gravity,
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
textColor: CupertinoColors.white,
|
||||||
|
fontSize: 16.0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _showCustomToast({
|
||||||
|
required String message,
|
||||||
|
required ToastType type,
|
||||||
|
required Duration duration,
|
||||||
|
required ToastGravity gravity,
|
||||||
|
required PageStandards standards,
|
||||||
|
}) {
|
||||||
|
Color backgroundColor;
|
||||||
|
IconData icon;
|
||||||
|
String emoji;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case ToastType.success:
|
||||||
|
backgroundColor = const Color(0xFF4CAF50);
|
||||||
|
icon = CupertinoIcons.checkmark_circle_fill;
|
||||||
|
emoji = '✅';
|
||||||
|
break;
|
||||||
|
case ToastType.error:
|
||||||
|
backgroundColor = const Color(0xFFF44336);
|
||||||
|
icon = CupertinoIcons.xmark_circle_fill;
|
||||||
|
emoji = '❌';
|
||||||
|
break;
|
||||||
|
case ToastType.warning:
|
||||||
|
backgroundColor = const Color(0xFFFF9800);
|
||||||
|
icon = CupertinoIcons.exclamationmark_triangle_fill;
|
||||||
|
emoji = '⚠️';
|
||||||
|
break;
|
||||||
|
case ToastType.info:
|
||||||
|
backgroundColor = standards.primaryColor;
|
||||||
|
icon = CupertinoIcons.info_circle_fill;
|
||||||
|
emoji = 'ℹ️';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget toast = Container(
|
||||||
|
padding: standards.scaledPadding(
|
||||||
|
EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||||
|
),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(standards.scaledRadius(12)),
|
||||||
|
color: backgroundColor,
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: backgroundColor.withOpacity(0.3),
|
||||||
|
blurRadius: 10,
|
||||||
|
offset: const Offset(0, 4),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
padding: standards.scaledPadding(EdgeInsets.all(4)),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: CupertinoColors.white.withOpacity(0.2),
|
||||||
|
borderRadius: BorderRadius.circular(standards.scaledRadius(8)),
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
icon,
|
||||||
|
color: CupertinoColors.white,
|
||||||
|
size: standards.scaledFontSize(20),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: standards.scaledWidth(12)),
|
||||||
|
Flexible(
|
||||||
|
child: Text(
|
||||||
|
message,
|
||||||
|
style: standards.textStyle.copyWith(
|
||||||
|
color: CupertinoColors.white,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
_fToast.showToast(
|
||||||
|
child: toast,
|
||||||
|
toastDuration: duration,
|
||||||
|
gravity: gravity,
|
||||||
|
fadeDuration: const Duration(milliseconds: 300),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<void> success(
|
||||||
|
String message, {
|
||||||
|
Duration duration = const Duration(seconds: 2),
|
||||||
|
ToastGravity gravity = ToastGravity.BOTTOM,
|
||||||
|
}) async {
|
||||||
|
await show(
|
||||||
|
message: message,
|
||||||
|
type: ToastType.success,
|
||||||
|
duration: duration,
|
||||||
|
gravity: gravity,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<void> error(
|
||||||
|
String message, {
|
||||||
|
Duration duration = const Duration(seconds: 2),
|
||||||
|
ToastGravity gravity = ToastGravity.BOTTOM,
|
||||||
|
}) async {
|
||||||
|
await show(
|
||||||
|
message: message,
|
||||||
|
type: ToastType.error,
|
||||||
|
duration: duration,
|
||||||
|
gravity: gravity,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<void> warning(
|
||||||
|
String message, {
|
||||||
|
Duration duration = const Duration(seconds: 2),
|
||||||
|
ToastGravity gravity = ToastGravity.BOTTOM,
|
||||||
|
}) async {
|
||||||
|
await show(
|
||||||
|
message: message,
|
||||||
|
type: ToastType.warning,
|
||||||
|
duration: duration,
|
||||||
|
gravity: gravity,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<void> info(
|
||||||
|
String message, {
|
||||||
|
Duration duration = const Duration(seconds: 2),
|
||||||
|
ToastGravity gravity = ToastGravity.BOTTOM,
|
||||||
|
}) async {
|
||||||
|
await show(
|
||||||
|
message: message,
|
||||||
|
type: ToastType.info,
|
||||||
|
duration: duration,
|
||||||
|
gravity: gravity,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void removeCustomToast() {
|
||||||
|
_fToast.removeCustomToast();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void removeQueuedCustomToasts() {
|
||||||
|
_fToast.removeQueuedCustomToasts();
|
||||||
|
}
|
||||||
|
}
|
||||||
1
packages/fluttertoast
Submodule
1
packages/fluttertoast
Submodule
Submodule packages/fluttertoast added at 60bfbda748
7
packages/fluttertoast_ohos/lib/fluttertoast_ohos.dart
Normal file
7
packages/fluttertoast_ohos/lib/fluttertoast_ohos.dart
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import 'fluttertoast_platform_interface.dart';
|
||||||
|
|
||||||
|
class FluttertoastOhos extends FluttertoastPlatform {
|
||||||
|
static void registerWith() {
|
||||||
|
FluttertoastPlatform.instance = FluttertoastOhos();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
abstract class FluttertoastPlatform {
|
||||||
|
static FluttertoastPlatform? instance;
|
||||||
|
|
||||||
|
static const MethodChannel _channel =
|
||||||
|
MethodChannel('PonnamKarthik/fluttertoast');
|
||||||
|
|
||||||
|
Future<bool?> showToast({
|
||||||
|
required String msg,
|
||||||
|
String? toastLength,
|
||||||
|
int timeInSecForIosWeb = 1,
|
||||||
|
double? fontSize,
|
||||||
|
String? fontAsset,
|
||||||
|
String? gravity,
|
||||||
|
int? backgroundColor,
|
||||||
|
int? textColor,
|
||||||
|
bool webShowClose = false,
|
||||||
|
String webBgColor = "linear-gradient(to right, #00b09b, #96c93d)",
|
||||||
|
String webPosition = "right",
|
||||||
|
}) async {
|
||||||
|
final Map<String, dynamic> params = <String, dynamic>{
|
||||||
|
'msg': msg,
|
||||||
|
'length': toastLength,
|
||||||
|
'time': timeInSecForIosWeb,
|
||||||
|
'gravity': gravity,
|
||||||
|
'bgcolor': backgroundColor,
|
||||||
|
'iosBgcolor': backgroundColor,
|
||||||
|
'textcolor': textColor,
|
||||||
|
'iosTextcolor': textColor,
|
||||||
|
'fontSize': fontSize,
|
||||||
|
'fontAsset': fontAsset,
|
||||||
|
'webShowClose': webShowClose,
|
||||||
|
'webBgColor': webBgColor,
|
||||||
|
'webPosition': webPosition
|
||||||
|
};
|
||||||
|
|
||||||
|
bool? res = await _channel.invokeMethod('showToast', params);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool?> cancel() async {
|
||||||
|
bool? res = await _channel.invokeMethod("cancel");
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
28
packages/fluttertoast_ohos/pubspec.yaml
Normal file
28
packages/fluttertoast_ohos/pubspec.yaml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
name: fluttertoast_ohos
|
||||||
|
description: Ohos implementation of the fluttertoast plugin.
|
||||||
|
repository: https://github.com/PonnamKarthik/FlutterToast
|
||||||
|
issue_tracker: https://github.com/ponnamkarthik/FlutterToast/issues
|
||||||
|
version: 9.0.0
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: ">=2.12.0 <4.0.0"
|
||||||
|
flutter: ">=1.10.0"
|
||||||
|
|
||||||
|
flutter:
|
||||||
|
plugin:
|
||||||
|
implements: fluttertoast
|
||||||
|
platforms:
|
||||||
|
ohos:
|
||||||
|
package: io.github.ponnamkarthik.toast.fluttertoast
|
||||||
|
pluginClass: FlutterToastPlugin
|
||||||
|
dartPluginClass: FluttertoastOhos
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
flutter:
|
||||||
|
sdk: flutter
|
||||||
|
fluttertoast:
|
||||||
|
path: ../fluttertoast
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
flutter_test:
|
||||||
|
sdk: flutter
|
||||||
172
pubspec.yaml
Normal file
172
pubspec.yaml
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
name: mom_kitchen
|
||||||
|
description: "A new Flutter project."
|
||||||
|
# The following line prevents the package from being accidentally published to
|
||||||
|
# pub.dev using `flutter pub publish`. This is preferred for private packages.
|
||||||
|
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||||
|
|
||||||
|
# The following defines the version and build number for your application.
|
||||||
|
# A version number is three numbers separated by dots, like 1.2.43
|
||||||
|
# followed by an optional build number separated by a +.
|
||||||
|
# Both the version and the builder number may be overridden in flutter
|
||||||
|
# build by specifying --build-name and --build-number, respectively.
|
||||||
|
# In Android, build-name is used as versionName while build-number used as versionCode.
|
||||||
|
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
|
||||||
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
|
||||||
|
# Read more about iOS versioning at
|
||||||
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
|
version: 1.0.0+1
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: ^3.9.2
|
||||||
|
|
||||||
|
# Dependencies specify other packages that your package needs in order to work.
|
||||||
|
# To automatically upgrade your package dependencies to the latest versions
|
||||||
|
# consider running `flutter pub upgrade --major-versions`. Alternatively,
|
||||||
|
# dependencies can be manually updated by changing the version numbers below to
|
||||||
|
# the latest version available on pub.dev. To see which dependencies have newer
|
||||||
|
# versions available, run `flutter pub outdated`.
|
||||||
|
dependencies:
|
||||||
|
flutter:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
|
# The following adds the Cupertino Icons font to your application.
|
||||||
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
|
cupertino_icons: ^1.0.8
|
||||||
|
|
||||||
|
# Internationalization support
|
||||||
|
flutter_localizations:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
|
dio: ^5.9.2
|
||||||
|
dio_cache_interceptor: ^3.5.0
|
||||||
|
platform_info: ^5.0.0
|
||||||
|
intl: ^0.20.2
|
||||||
|
pretty_dio_logger: ^1.4.0
|
||||||
|
logger: ^2.7.0
|
||||||
|
|
||||||
|
|
||||||
|
flutter_adaptive_scaffold:
|
||||||
|
git:
|
||||||
|
url: "https://gitcode.com/openharmony-tpc/flutter_packages.git"
|
||||||
|
path: "packages/flutter_adaptive_scaffold"
|
||||||
|
shared_preferences:
|
||||||
|
git:
|
||||||
|
url: "https://gitcode.com/openharmony-tpc/flutter_packages.git"
|
||||||
|
path: "packages/shared_preferences/shared_preferences"
|
||||||
|
|
||||||
|
get:
|
||||||
|
git:
|
||||||
|
url: https://gitcode.com/openharmony-sig/fluttertpc_get
|
||||||
|
|
||||||
|
# orientation:
|
||||||
|
# git:
|
||||||
|
# url: https://gitcode.com/openharmony-sig/fluttertpc_orientation.git
|
||||||
|
|
||||||
|
animations:
|
||||||
|
git:
|
||||||
|
url: https://gitcode.com/openharmony-sig/flutter_packages.git
|
||||||
|
path: "packages/animations"
|
||||||
|
ref: br_animations-v2.0.11_ohos
|
||||||
|
|
||||||
|
fluttertoast:
|
||||||
|
path: packages/fluttertoast
|
||||||
|
|
||||||
|
pigeon:
|
||||||
|
git:
|
||||||
|
url: "https://gitcode.com/openharmony-sig/flutter_packages.git"
|
||||||
|
path: "packages/pigeon"
|
||||||
|
share_plus:
|
||||||
|
git:
|
||||||
|
url: https://gitcode.com/openharmony-sig/flutter_plus_plugins.git
|
||||||
|
path: packages/share_plus/share_plus
|
||||||
|
ref: br_share_plus-v10.1.1_ohos
|
||||||
|
connectivity_plus:
|
||||||
|
git:
|
||||||
|
url: https://gitcode.com/openharmony-sig/flutter_plus_plugins.git
|
||||||
|
path: packages/connectivity_plus/connectivity_plus
|
||||||
|
flutter_local_notifications:
|
||||||
|
git:
|
||||||
|
url: https://gitcode.com/openharmony-sig/fluttertpc_flutter_local_notifications.git
|
||||||
|
path: flutter_local_notifications
|
||||||
|
ref: br_flutter_local_notifications-v17.2.4_ohos
|
||||||
|
package_info_plus:
|
||||||
|
git:
|
||||||
|
url: https://gitcode.com/openharmony-sig/flutter_plus_plugins.git
|
||||||
|
path: packages/package_info_plus/package_info_plus
|
||||||
|
ref: br_package_info_plus-v8.1.0_ohos
|
||||||
|
permission_handler:
|
||||||
|
git:
|
||||||
|
url: https://gitcode.com/openharmony-sig/flutter_permission_handler.git
|
||||||
|
path: permission_handler
|
||||||
|
ref: br_permission_handler_v11.3.1_ohos
|
||||||
|
|
||||||
|
device_info_plus:
|
||||||
|
git:
|
||||||
|
url: https://gitcode.com/openharmony-sig/flutter_plus_plugins.git
|
||||||
|
path: packages/device_info_plus/device_info_plus
|
||||||
|
|
||||||
|
flutter_screenutil:
|
||||||
|
path: packages/flutter_screenutil
|
||||||
|
|
||||||
|
path_provider:
|
||||||
|
git:
|
||||||
|
url: "https://gitcode.com/openharmony-sig/flutter_packages.git"
|
||||||
|
path: "packages/path_provider/path_provider"
|
||||||
|
ref: master
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
flutter_test:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
|
# The "flutter_lints" package below contains a set of recommended lints to
|
||||||
|
# encourage good coding practices. The lint set provided by the package is
|
||||||
|
# activated in the `analysis_options.yaml` file located at the root of your
|
||||||
|
# package. See that file for information about deactivating specific lint
|
||||||
|
# rules and activating additional ones.
|
||||||
|
flutter_lints: ^6.0.0
|
||||||
|
|
||||||
|
# For information on the generic Dart part of this file, see the
|
||||||
|
# following page: https://dart.dev/tools/pub/pubspec
|
||||||
|
|
||||||
|
# The following section is specific to Flutter packages.
|
||||||
|
flutter:
|
||||||
|
|
||||||
|
# The following line ensures that the Material Icons font is
|
||||||
|
# included with your application, so that you can use the icons in
|
||||||
|
# the material Icons class.
|
||||||
|
uses-material-design: true
|
||||||
|
|
||||||
|
# Enable generation of localized strings
|
||||||
|
generate: true
|
||||||
|
# To add assets to your application, add an assets section, like this:
|
||||||
|
# assets:
|
||||||
|
# - images/a_dot_burr.jpeg
|
||||||
|
# - images/a_dot_ham.jpeg
|
||||||
|
|
||||||
|
# An image asset can refer to one or more resolution-specific "variants", see
|
||||||
|
# https://flutter.dev/to/resolution-aware-images
|
||||||
|
|
||||||
|
# For details regarding adding assets from package dependencies, see
|
||||||
|
# https://flutter.dev/to/asset-from-package
|
||||||
|
|
||||||
|
# To add custom fonts to your application, add a fonts section here,
|
||||||
|
# in this "flutter" section. Each entry in this list should have a
|
||||||
|
# "family" key with the font family name, and a "fonts" key with a
|
||||||
|
# list giving the asset and other descriptors for the font. For
|
||||||
|
# example:
|
||||||
|
# fonts:
|
||||||
|
# - family: Schyler
|
||||||
|
# fonts:
|
||||||
|
# - asset: fonts/Schyler-Regular.ttf
|
||||||
|
# - asset: fonts/Schyler-Italic.ttf
|
||||||
|
# style: italic
|
||||||
|
# - family: Trajan Pro
|
||||||
|
# fonts:
|
||||||
|
# - asset: fonts/TrajanPro.ttf
|
||||||
|
# - asset: fonts/TrajanPro_Bold.ttf
|
||||||
|
# weight: 700
|
||||||
|
#
|
||||||
|
# For details regarding fonts from package dependencies,
|
||||||
|
# see https://flutter.dev/to/font-from-package
|
||||||
Reference in New Issue
Block a user