import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../modules/kr_home/views/hi_subscription_corner_button.dart'; import 'package:kaer_with_panels/main.dart'; import 'package:kaer_with_panels/app/widgets/kr_local_image.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:kaer_with_panels/app/routes/app_pages.dart'; class GlobalOverlayService extends GetxService { Color? _currentColor; static GlobalOverlayService get instance => Get.find(); VoidCallback? _subscriptionAnimationTrigger; void registerAnimationTrigger(VoidCallback trigger) { _subscriptionAnimationTrigger = trigger; } /// 触发按钮动画跳转购买页 void triggerSubscriptionAnimation() { if (_subscriptionAnimationTrigger != null) { _subscriptionAnimationTrigger!.call(); } else { print('🔥 Subscription animation trigger not registered yet'); } } OverlayEntry? _overlayEntry; final RxBool _isVisible = false.obs; final RxString _currentRoute = ''.obs; bool get isVisible => _isVisible.value; void updateCurrentRoute(String route) { _currentRoute.value = route; } @override void onInit() { super.onInit(); print('🔥 GlobalOverlayService: Service initialized'); } void showSubscriptionButton([OverlayState? overlay]) { if (_isVisible.value) return; WidgetsBinding.instance.addPostFrameCallback((_) { _doShowSubscriptionButton(overlay); }); } void _doShowSubscriptionButton([OverlayState? overlay, Color? color]) { print('🔥 _doShowSubscriptionButton called, overlay=$overlay'); if (_isVisible.value) return; try { overlay ??= navigatorKey.currentState?.overlay; if (overlay == null) { print('🔥 GlobalOverlayService: No overlay found, cannot show subscription button'); return; } _overlayEntry = OverlayEntry( builder: (context) { final statusBarHeight = MediaQuery.of(context).padding.top < 62 ? 62 : MediaQuery.of(context).padding.top; final double radius = 40.0 + statusBarHeight; final double diameter = radius * 2; return Stack( children: [ // 1️⃣ 圆背景,保持原来位置 Positioned( top: -(diameter - (radius + statusBarHeight)), right: -(radius - (statusBarHeight / 2)), width: diameter, height: diameter, child: HISubscriptionCornerButton( size: diameter, color: _currentColor ?? Theme.of(context).primaryColor, topOffset: -radius, rightOffset: -radius, ), ), // 2️⃣ money-icon,独立定位,固定在屏幕右上角 Positioned( top: MediaQuery.of(context).padding.top, right: (radius / 2), child: FractionalTranslation( // Offset 的第一个参数是 x,第二个是 y // 0.5 代表向右偏移自身宽度的 50%,-0.5 代表向左偏移自身宽度的 50% translation: const Offset(0.5, 0), child: GestureDetector( behavior: HitTestBehavior.translucent, onTap: () { print('🔥 money-icon tapped'); GlobalOverlayService.instance.triggerSubscriptionAnimation(); }, child: IgnorePointer( ignoring: false, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ KrLocalImage( imageName: 'money-icon', imageType: ImageType.svg, width: 32.w, // 建议固定宽度以保证计算准确 ), SizedBox(height: 2.w), Obx(() { final current = _currentRoute.value; print('🔥 GlobalOverlayService Obx: currentRoute = $current'); // ✅ 结合三种方式判断:1. 显式设为透明 2. 路由名称匹配 3. 包含关键特征 bool isHidden = _currentColor == Colors.transparent || current == Routes.KR_PURCHASE_MEMBERSHIP || current.contains(Routes.KR_PURCHASE_MEMBERSHIP) || Routes.KR_PURCHASE_MEMBERSHIP.contains(current) || current == Routes.KR_ORDER_STATUS || current.contains('purchase-membership'); if (isHidden) { return const SizedBox.shrink(); } return DefaultTextStyle( style: const TextStyle( decoration: TextDecoration.none, // 核心:显式声明无装饰 ), child: Text( '购买套餐', style: TextStyle( color: Colors.black, fontSize: 12.sp, fontWeight: FontWeight.w600, decoration: TextDecoration.none, // 也可以在这里直接写 ), ), ); }), ], ), ), ), ), ), ], ); }, ); overlay.insert(_overlayEntry!); _isVisible.value = true; print('🔥 GlobalOverlayService: Subscription button shown successfully'); } catch (e) { print('🔥 GlobalOverlayService: Error showing subscription button: $e'); } } void hideSubscriptionButton() { if (!_isVisible.value) return; _overlayEntry?.remove(); _overlayEntry = null; _isVisible.value = false; } void toggleSubscriptionButton() { if (_isVisible.value) { hideSubscriptionButton(); } else { showSubscriptionButton(); } } void safeShowSubscriptionButton() { void _attemptShow() { final overlay = navigatorKey.currentState?.overlay; if (overlay == null) { print('🔥 Overlay not ready, retrying...'); Future.delayed(const Duration(milliseconds: 200), _attemptShow); return; } WidgetsBinding.instance.addPostFrameCallback((_) { print('🔥 Overlay ready, inserting subscription button'); showSubscriptionButton(overlay); }); } _attemptShow(); } void updateSubscriptionButtonColor(Color? color) { if (_overlayEntry == null) { print('🔥 updateSubscriptionButtonColor: OverlayEntry is null'); return; } _currentColor = color; _overlayEntry!.markNeedsBuild(); // 🔥 强制刷新 UI } void forceShowSubscriptionButton() { print('🔥 GlobalOverlayService: Force showing subscription button'); hideSubscriptionButton(); Future.delayed(const Duration(milliseconds: 100), () { safeShowSubscriptionButton(); }); } @override void onClose() { hideSubscriptionButton(); super.onClose(); } }