Files
huangguo_android/lib/hj_page/video/video_full_page.dart
T
2026-09-15 15:44:13 +07:00

111 lines
3.5 KiB
Dart

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<VideoFullPage> createState() => _VideoFullPageState();
}
// tag 隔离:logic 持有外部传入的 playCtr。不加 tag 时上一个全屏页的 Get.delete 若没跑完,
// GetBuilder 的 init 会被跳过 → 复用旧 logic、播到上一个视频
class _VideoFullPageState extends State<VideoFullPage> with UniqueTagMixin {
VideoPlayerController get playCtr => widget.playCtr;
@override
Widget build(BuildContext context) {
return GetBuilder<VideoFullLogic>(
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),
),
),
),
),
);
}
}