import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:hgdj/hj_page/video/video_full_logic.dart'; import 'package:hgdj/hj_page/video/view/video_menu_view.dart'; import 'package:video_player/video_player.dart'; import '../../hj_model/video_model.dart'; import '../../hj_utils/screen.dart'; import '../../tools_base/unique_tag_mixin.dart'; /// 全屏播放页(复用外部传入的播放器控制器,不新建也不释放) class VideoFullPage extends StatefulWidget { final VideoPlayerController playCtr; final VideoModel? videoModel; final bool isAutoV; // 判断size,自动转竖屏 final bool showMenu; //是否需要显示菜单栏,直播不需要展示菜单栏 const VideoFullPage({ super.key, required this.playCtr, this.videoModel, this.isAutoV = true, this.showMenu = true, }); @override State createState() => _VideoFullPageState(); } // tag 隔离:logic 持有外部传入的 playCtr。不加 tag 时上一个全屏页的 Get.delete 若没跑完, // GetBuilder 的 init 会被跳过 → 复用旧 logic、播到上一个视频 class _VideoFullPageState extends State with UniqueTagMixin { VideoPlayerController get playCtr => widget.playCtr; @override Widget build(BuildContext context) { return GetBuilder( tag: uniqueTag, init: VideoFullLogic(playCtr: playCtr, isAutoV: widget.isAutoV), builder: (logic) => PopScope( // 系统返回键/侧滑不直接退页,先恢复竖屏再由 exitFullScreen 退 canPop: false, onPopInvokedWithResult: (didPop, _) { if (didPop) return; logic.exitFullScreen(); }, child: Scaffold( backgroundColor: Colors.black, body: Stack( alignment: Alignment.center, children: [ // 撑满 Stack 用(Stack 尺寸取最大的非 Positioned 子节点)。 // 不能改成 StackFit.expand:那会给 AspectRatio 传 tight 约束,视频比例失效 SizedBox(width: screen.screenWidth, height: screen.screenHeight), Hero( tag: "player", child: AspectRatio( aspectRatio: logic.aspectRatio, child: VideoPlayer(playCtr), ), ), if (widget.showMenu) _menuLayer(logic), _backBtn(logic), ], ), ), ), ); } /// 播放器控制层(进度条/倍速/快进快退) Widget _menuLayer(VideoFullLogic logic) { return Positioned( bottom: 5, left: 0, right: 0, child: SizedBox( width: screen.screenWidth, height: screen.screenHeight, child: VideoMenuView( playCtr: playCtr, isFull: true, onFullScreen: logic.exitFullScreen, videoModel: widget.videoModel, ), ), ); } /// 全屏(横屏)下返回按钮避开刘海/状态栏安全区(原来用竖屏的 paddingTop 不准) Widget _backBtn(VideoFullLogic logic) { return SafeArea( child: Align( alignment: Alignment.topLeft, child: InkWell( enableFeedback: false, onTap: logic.exitFullScreen, child: const Padding( padding: EdgeInsets.fromLTRB(5, 5, 15, 15), child: SizedBox( width: 30, height: 30, child: Icon(Icons.arrow_back_ios_sharp, color: Colors.white), ), ), ), ), ); } }