import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/svg.dart'; import 'package:vibration/vibration.dart'; import 'package:maibu_satabot_v2/core/localization/app_localizations.dart'; import '../bloc/remote_control_cubit.dart'; class EmergencyStopButton extends StatefulWidget { final double width; const EmergencyStopButton({ Key? key, this.width = 120, }) : super(key: key); @override State createState() => _EmergencyStopButtonState(); } class _EmergencyStopButtonState extends State with SingleTickerProviderStateMixin { late AnimationController _progressController; bool _isPressing = false; @override void initState() { super.initState(); _progressController = AnimationController( vsync: this, duration: const Duration(seconds: 3), ); // 添加监听器,确保动画值变化时重建 UI _progressController.addListener(() { if (mounted) { setState(() {}); } }); } @override void dispose() { _progressController.dispose(); super.dispose(); } void _resetProgress() { setState(() => _isPressing = false); _progressController.stop(); _progressController.value = 0; } @override Widget build(BuildContext context) { final isEmergencyActive = context .watch() .state .isEmergency; final width = widget.width * 0.65; final double indicatorSize = width + 20; return SizedBox( width: indicatorSize, height: indicatorSize, child: Stack( alignment: Alignment.center, children: [ // 进度环 - 只在按压时显示 AnimatedOpacity( opacity: _isPressing ? 1.0 : 0.0, duration: const Duration(milliseconds: 200), child: SizedBox( width: indicatorSize, height: indicatorSize, child: CircularProgressIndicator( value: _progressController.value, strokeWidth: 6, color: Colors.red.withOpacity(0.9), backgroundColor: Colors.red.withValues(alpha: 0.2), ), ), ), // 按钮主体 GestureDetector( onTap: () { debugPrint('🔴 [点击] 触发急停'); _triggerVibration(); if (!isEmergencyActive) { context.read().updateEmergency(true); context.read().toggleLock(); HapticFeedback.heavyImpact(); } }, onLongPressStart: (_) { debugPrint('🔴 [长按开始] isEmergency=$isEmergencyActive'); _triggerVibration(); if (isEmergencyActive && !_isPressing) { setState(() => _isPressing = true); debugPrint('🔴 [开始动画] 从 0 开始'); _triggerVibration(); _progressController.reset(); _progressController.forward().then((_) { debugPrint('🔴 [动画完成] _isPressing=$_isPressing'); if (_isPressing && mounted) { debugPrint('✅ [解除急停] 执行'); _triggerVibration(); context.read().updateEmergency(false); context.read().toggleLock(); HapticFeedback.vibrate(); setState(() => _isPressing = false); } }); } }, onLongPressEnd: (_) { _triggerVibration(); debugPrint('🔴 [长按结束]'); if (_isPressing) { _resetProgress(); } }, onLongPressCancel: () { _triggerVibration(); debugPrint('🔴 [长按取消]'); if (_isPressing) { _resetProgress(); } }, child: Container( width: width, height: width, decoration: BoxDecoration( shape: BoxShape.circle, color: isEmergencyActive ? Colors.red.withOpacity(0.5) : const Color(0x80C53030), boxShadow: isEmergencyActive ? [ BoxShadow( color: Colors.red.withValues(alpha: 0.5), blurRadius: 20, ), ] : [], ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ SvgPicture.asset( 'assets/svgs/remote_alert.svg', width: width * 0.4, color: Colors.white.withValues(alpha: 0.5), ), const SizedBox(height: 6), Text( isEmergencyActive ? AppLocalizations.of(context).translate('remote_control.emergency_stopping') : AppLocalizations.of(context).translate('remote_control.emergency_stop'), style: TextStyle( color: Colors.white.withValues(alpha: 0.5), fontSize: 14, fontWeight: FontWeight.w900, ), ), ], ), ), ), ], ), ); } void _triggerVibration() { Vibration.hasVibrator().then((hasVibrator) { if (hasVibrator ?? false) { Vibration.vibrate(duration: 50, amplitude: 380); debugPrint(' 震动执行 - 10ms'); } else { debugPrint(' 设备不支持震动'); } }).catchError((e) { debugPrint('震动失败:$e'); }); } }