import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:star_lock/appRouters.dart'; import 'package:star_lock/app_settings/app_colors.dart'; import 'package:star_lock/talk/call/callTalk.dart'; import 'package:star_lock/talk/starChart/constant/talk_status.dart'; import 'package:star_lock/talk/starChart/star_chart_manage.dart'; import 'package:star_lock/talk/starChart/views/imageTransmission/image_transmission_logic.dart'; import 'package:star_lock/talk/starChart/views/imageTransmission/image_transmission_state.dart'; import 'package:star_lock/tools/titleAppBar.dart'; import 'package:slide_to_act/slide_to_act.dart'; // 可选:引入第三方滑动解锁库 // import 'package:flutter_slider_button/flutter_slider_button.dart'; class ImageTransmissionPage extends StatefulWidget { const ImageTransmissionPage(); @override State createState() => _ImageTransmissionPageState(); } class _ImageTransmissionPageState extends State with TickerProviderStateMixin { final ImageTransmissionLogic logic = Get.put(ImageTransmissionLogic()); final ImageTransmissionState state = Get.find().state; final startChartManage = StartChartManage(); @override void initState() { super.initState(); state.animationController = AnimationController( vsync: this, // 确保使用的TickerProvider是当前Widget duration: const Duration(seconds: 1), ); state.animationController.repeat(); state.animationController.addStatusListener((AnimationStatus status) { if (status == AnimationStatus.completed) { state.animationController.reset(); state.animationController.forward(); } else if (status == AnimationStatus.dismissed) { state.animationController.reset(); state.animationController.forward(); } }); } @override void dispose() { state.animationController.dispose(); CallTalk().finishAVData(); super.dispose(); } String handlerAppBarTitle() { if (startChartManage.rotateAngle == 0 && startChartManage.videoWidth == 640 && startChartManage.videoHeight == 480) { return ''; } return '图传'.tr; } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: AppColors.mainBackgroundColor, resizeToAvoidBottomInset: false, appBar: TitleAppBar( barTitle: handlerAppBarTitle(), haveBack: true, backgroundColor: AppColors.mainColor, backAction: () { logic.udpHangUpAction(); }, actionsList: [ Visibility( visible: state.currentLanguage == 'zh_CN' && Platform.isAndroid, child: IconButton( icon: Icon( Icons.notification_add_sharp, size: 32.w, color: Colors.white, ), onPressed: () { Get.toNamed(Routers.permissionGuidancePage); }, ), ) ], ), body: Obx(() => Column( children: [ SizedBox(height: 24.h), SizedBox( height: 0.6.sh, child: state.listData.value.isEmpty ? _buildWaitingView() : _buildVideoView(), ), SizedBox(height: 30.h), _buildBottomToolBar(), SizedBox(height: 30.h), ], )), ); } Widget _buildWaitingView() { double barWidth = MediaQuery.of(context).size.width - 60.w; return Center( child: ClipRRect( borderRadius: BorderRadius.circular(30.h), child: Stack( alignment: Alignment.center, children: [ Container( width: barWidth, height: double.infinity, child: Image.asset( 'images/main/monitorBg.png', fit: BoxFit.cover, ), ), RotationTransition( turns: state.animationController, child: Image.asset( 'images/main/realTime_connecting.png', width: 300.w, height: 300.w, fit: BoxFit.contain, ), ), ], ), ), ); } Widget _buildVideoView() { double barWidth = MediaQuery.of(context).size.width - 60.w; return PopScope( canPop: false, child: RepaintBoundary( key: state.globalKey, child: Center( child: ClipRRect( borderRadius: BorderRadius.circular(30.h), child: Container( width: barWidth, // height: double.infinity, child: RotatedBox( quarterTurns: startChartManage.rotateAngle ~/ 90, child: RawImage( image: state.currentImage.value, fit: BoxFit.cover, filterQuality: FilterQuality.high, ), ), ), ), ), ), ); } Widget _buildBottomToolBar() { return Container( margin: EdgeInsets.symmetric(horizontal: 30.w), padding: EdgeInsets.symmetric(vertical: 28.h, horizontal: 20.w), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(30.h), boxShadow: [ BoxShadow( color: Colors.black12, blurRadius: 12, offset: Offset(0, 4), ), ], ), child: Column( mainAxisSize: MainAxisSize.min, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ _circleButton( icon: Icons.call, color: Colors.green, onTap: () { if (state.talkStatus.value == TalkStatus.passiveCallWaitingAnswer) { // 接听 logic.initiateAnswerCommand(); } }, ), _circleButton( icon: Icons.call_end, color: Colors.red, onTap: () { logic.udpHangUpAction(); }, ), _circleButton( icon: Icons.camera_alt, color: Colors.blue, onTap: () async { await logic.captureAndSavePng(); }, ), ], ), SizedBox(height: 36.h), SlideAction( height: 64.h, borderRadius: 24.h, elevation: 0, innerColor: Colors.amber, outerColor: Colors.amber.withOpacity(0.15), sliderButtonIcon: Icon(Icons.lock, color: Colors.white, size: 40.w), text: '滑动解锁', textStyle: TextStyle( fontSize: 26.sp, color: Colors.black54, fontWeight: FontWeight.bold), onSubmit: () { // TODO: 实现滑动解锁逻辑 logic.remoteOpenLock(); }, ), ], ), ); } Widget _circleButton( {required IconData icon, required Color color, required VoidCallback onTap}) { return GestureDetector( onTap: onTap, child: Container( width: 90.w, height: 90.w, decoration: BoxDecoration( color: color, shape: BoxShape.circle, boxShadow: [ BoxShadow( color: color.withOpacity(0.3), blurRadius: 10, offset: Offset(0, 4), ), ], ), child: Icon(icon, color: Colors.white, size: 48.w), ), ); } }