diff --git a/lib/pages/bangumi/introduction/view.dart b/lib/pages/bangumi/introduction/view.dart index f9efc66c5..4459bf7e0 100644 --- a/lib/pages/bangumi/introduction/view.dart +++ b/lib/pages/bangumi/introduction/view.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:get/get.dart'; -import 'package:hive/hive.dart'; import 'package:pilipala/common/constants.dart'; import 'package:pilipala/common/widgets/badge.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart'; @@ -15,7 +14,6 @@ import 'package:pilipala/pages/video/detail/introduction/widgets/action_item.dar import 'package:pilipala/pages/video/detail/introduction/widgets/action_row_item.dart'; import 'package:pilipala/pages/video/detail/introduction/widgets/fav_panel.dart'; import 'package:pilipala/utils/feed_back.dart'; -import 'package:pilipala/utils/storage.dart'; import 'controller.dart'; import 'widgets/intro_detail.dart'; @@ -116,9 +114,7 @@ class _BangumiInfoState extends State { String heroTag = Get.arguments['heroTag']; late final BangumiIntroController bangumiIntroController; late final VideoDetailController videoDetailCtr; - Box localCache = GStrorage.localCache; late final BangumiInfoModel? bangumiItem; - late double sheetHeight; int? cid; bool isProcessing = false; void Function()? handleState(Future Function() action) { @@ -137,7 +133,6 @@ class _BangumiInfoState extends State { bangumiIntroController = Get.put(BangumiIntroController(), tag: heroTag); videoDetailCtr = Get.find(tag: heroTag); bangumiItem = bangumiIntroController.bangumiItem; - sheetHeight = localCache.get('sheetHeight'); cid = widget.cid!; print('cid: $cid'); videoDetailCtr.cid.listen((p0) { @@ -369,7 +364,6 @@ class _BangumiInfoState extends State { (bangumiItem != null ? bangumiItem!.episodes!.first.cid : widget.bangumiDetail!.episodes!.first.cid), - sheetHeight: sheetHeight, changeFuc: (bvid, cid, aid) => bangumiIntroController .changeSeasonOrbangu(bvid, cid, aid), ) diff --git a/lib/pages/bangumi/introduction/widgets/intro_detail.dart b/lib/pages/bangumi/introduction/widgets/intro_detail.dart index c5bbd5663..87a069b95 100644 --- a/lib/pages/bangumi/introduction/widgets/intro_detail.dart +++ b/lib/pages/bangumi/introduction/widgets/intro_detail.dart @@ -1,11 +1,8 @@ import 'package:flutter/material.dart'; -import 'package:hive/hive.dart'; +import 'package:get/get.dart'; import 'package:pilipala/common/widgets/stat/danmu.dart'; import 'package:pilipala/common/widgets/stat/view.dart'; -import 'package:pilipala/utils/storage.dart'; -Box localCache = GStrorage.localCache; -late double sheetHeight; class IntroDetail extends StatelessWidget { final dynamic bangumiDetail; @@ -17,7 +14,6 @@ class IntroDetail extends StatelessWidget { @override Widget build(BuildContext context) { - sheetHeight = localCache.get('sheetHeight'); TextStyle smallTitle = TextStyle( fontSize: 12, color: Theme.of(context).colorScheme.onBackground, @@ -25,7 +21,7 @@ class IntroDetail extends StatelessWidget { return Container( color: Theme.of(context).colorScheme.background, padding: const EdgeInsets.only(left: 14, right: 14), - height: sheetHeight, + height: context.height.abs() * 0.7, child: Column( children: [ Container( diff --git a/lib/pages/bangumi/widgets/bangumi_panel.dart b/lib/pages/bangumi/widgets/bangumi_panel.dart index 5996d6c82..deaad5265 100644 --- a/lib/pages/bangumi/widgets/bangumi_panel.dart +++ b/lib/pages/bangumi/widgets/bangumi_panel.dart @@ -12,13 +12,11 @@ class BangumiPanel extends StatefulWidget { super.key, required this.pages, this.cid, - this.sheetHeight, this.changeFuc, }); final List pages; final int? cid; - final double? sheetHeight; final Function? changeFuc; @override @@ -80,7 +78,7 @@ class _BangumiPanelState extends State { }); // 在这里使用 setState 更新状态 return Container( - height: widget.sheetHeight, + height: context.height.abs() * 0.7, color: Theme.of(context).colorScheme.background, child: Column( children: [ diff --git a/lib/pages/main/view.dart b/lib/pages/main/view.dart index 04e0f087f..bf8a6cb1c 100644 --- a/lib/pages/main/view.dart +++ b/lib/pages/main/view.dart @@ -89,10 +89,6 @@ class _MainAppState extends State with SingleTickerProviderStateMixin { Widget build(BuildContext context) { Box localCache = GStrorage.localCache; double statusBarHeight = MediaQuery.of(context).padding.top; - double sheetHeight = MediaQuery.sizeOf(context).height - - MediaQuery.of(context).padding.top - - MediaQuery.sizeOf(context).width * 9 / 16; - localCache.put('sheetHeight', sheetHeight); localCache.put('statusBarHeight', statusBarHeight); return PopScope( canPop: false, diff --git a/lib/pages/video/detail/controller.dart b/lib/pages/video/detail/controller.dart index 440a6383e..e9e98a83e 100644 --- a/lib/pages/video/detail/controller.dart +++ b/lib/pages/video/detail/controller.dart @@ -241,6 +241,10 @@ class VideoDetailController extends GetxController plPlayerController.headerControl = headerControl; } + void setTriggerFullScreenCallback(void Function({bool? status}) callback) { + plPlayerController.setTriggerFullscreenCallback(callback); + } + // 视频链接 Future queryVideoUrl() async { var result = await VideoHttp.videoUrl(cid: cid.value, bvid: bvid); @@ -359,7 +363,7 @@ class VideoDetailController extends GetxController if (result['code'] == -404) { isShowCover.value = false; } - if (result['code'] == 87008){ + if (result['code'] == 87008) { SmartDialog.showToast("当前视频可能是专属视频,可能需包月充电观看(${result['msg']})"); } else { SmartDialog.showToast("错误(${result['code']}):${result['msg']}"); diff --git a/lib/pages/video/detail/introduction/view.dart b/lib/pages/video/detail/introduction/view.dart index ea72d3231..850f8a28f 100644 --- a/lib/pages/video/detail/introduction/view.dart +++ b/lib/pages/video/detail/introduction/view.dart @@ -123,9 +123,7 @@ class _VideoInfoState extends State with TickerProviderStateMixin { late final VideoDetailController videoDetailCtr; late final Map videoItem; - final Box localCache = GStrorage.localCache; final Box setting = GStrorage.setting; - late double sheetHeight; late final bool loadingStatus; // 加载状态 @@ -153,7 +151,6 @@ class _VideoInfoState extends State with TickerProviderStateMixin { videoIntroController = Get.put(VideoIntroController(), tag: heroTag); videoDetailCtr = Get.find(tag: heroTag); videoItem = videoIntroController.videoItem!; - sheetHeight = localCache.get('sheetHeight'); loadingStatus = widget.loadingStatus; owner = loadingStatus ? videoItem['owner'] : widget.videoDetail!.owner; @@ -381,7 +378,6 @@ class _VideoInfoState extends State with TickerProviderStateMixin { cid: videoIntroController.lastPlayCid.value != 0 ? videoIntroController.lastPlayCid.value : widget.videoDetail!.pages!.first.cid, - sheetHeight: sheetHeight, changeFuc: (bvid, cid, aid) => videoIntroController .changeSeasonOrbangu(bvid, cid, aid), ), @@ -393,7 +389,6 @@ class _VideoInfoState extends State with TickerProviderStateMixin { Obx(() => PagesPanel( pages: widget.videoDetail!.pages!, cid: videoIntroController.lastPlayCid.value, - sheetHeight: sheetHeight, changeFuc: (cid) => videoIntroController.changeSeasonOrbangu( videoIntroController.bvid, cid, null), diff --git a/lib/pages/video/detail/introduction/widgets/fav_panel.dart b/lib/pages/video/detail/introduction/widgets/fav_panel.dart index 517caeaa0..304cd982d 100644 --- a/lib/pages/video/detail/introduction/widgets/fav_panel.dart +++ b/lib/pages/video/detail/introduction/widgets/fav_panel.dart @@ -1,9 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hive/hive.dart'; import 'package:pilipala/common/widgets/http_error.dart'; import 'package:pilipala/utils/feed_back.dart'; -import 'package:pilipala/utils/storage.dart'; class FavPanel extends StatefulWidget { const FavPanel({super.key, this.ctr}); @@ -14,21 +12,18 @@ class FavPanel extends StatefulWidget { } class _FavPanelState extends State { - final Box localCache = GStrorage.localCache; - late double sheetHeight; late Future _futureBuilderFuture; @override void initState() { super.initState(); - sheetHeight = localCache.get('sheetHeight'); _futureBuilderFuture = widget.ctr!.queryVideoInFolder(); } @override Widget build(BuildContext context) { return Container( - height: sheetHeight, + height: context.height.abs() * 0.7, color: Theme.of(context).colorScheme.background, child: Column( children: [ diff --git a/lib/pages/video/detail/introduction/widgets/group_panel.dart b/lib/pages/video/detail/introduction/widgets/group_panel.dart index 64ff913d7..60cf7650d 100644 --- a/lib/pages/video/detail/introduction/widgets/group_panel.dart +++ b/lib/pages/video/detail/introduction/widgets/group_panel.dart @@ -1,12 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; -import 'package:hive/hive.dart'; import 'package:pilipala/common/widgets/http_error.dart'; import 'package:pilipala/http/member.dart'; import 'package:pilipala/models/member/tags.dart'; import 'package:pilipala/utils/feed_back.dart'; -import 'package:pilipala/utils/storage.dart'; class GroupPanel extends StatefulWidget { final int? mid; @@ -17,8 +15,6 @@ class GroupPanel extends StatefulWidget { } class _GroupPanelState extends State { - final Box localCache = GStrorage.localCache; - late double sheetHeight; late Future _futureBuilderFuture; late List tagsList; bool showDefault = true; @@ -26,7 +22,6 @@ class _GroupPanelState extends State { @override void initState() { super.initState(); - sheetHeight = localCache.get('sheetHeight'); _futureBuilderFuture = MemberHttp.followUpTags(); } @@ -56,7 +51,7 @@ class _GroupPanelState extends State { @override Widget build(BuildContext context) { return Container( - height: sheetHeight, + height: context.height.abs() * 0.7, color: Theme.of(context).colorScheme.background, child: Column( children: [ diff --git a/lib/pages/video/detail/introduction/widgets/intro_detail.dart b/lib/pages/video/detail/introduction/widgets/intro_detail.dart index 59ed10a35..fec06ad8e 100644 --- a/lib/pages/video/detail/introduction/widgets/intro_detail.dart +++ b/lib/pages/video/detail/introduction/widgets/intro_detail.dart @@ -2,15 +2,10 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; -import 'package:hive/hive.dart'; import 'package:pilipala/common/widgets/stat/danmu.dart'; import 'package:pilipala/common/widgets/stat/view.dart'; -import 'package:pilipala/utils/storage.dart'; import 'package:pilipala/utils/utils.dart'; -Box localCache = GStrorage.localCache; -late double sheetHeight; - class IntroDetail extends StatelessWidget { const IntroDetail({ super.key, @@ -20,11 +15,10 @@ class IntroDetail extends StatelessWidget { @override Widget build(BuildContext context) { - sheetHeight = localCache.get('sheetHeight'); return Container( color: Theme.of(context).colorScheme.background, padding: const EdgeInsets.only(left: 14, right: 14), - height: sheetHeight, + height: context.height.abs() * 0.7, child: Column( children: [ InkWell( diff --git a/lib/pages/video/detail/introduction/widgets/page.dart b/lib/pages/video/detail/introduction/widgets/page.dart index 2ba7f507c..6477ae3f6 100644 --- a/lib/pages/video/detail/introduction/widgets/page.dart +++ b/lib/pages/video/detail/introduction/widgets/page.dart @@ -8,12 +8,10 @@ class PagesPanel extends StatefulWidget { super.key, required this.pages, this.cid, - this.sheetHeight, this.changeFuc, }); final List pages; final int? cid; - final double? sheetHeight; final Function? changeFuc; @override @@ -96,7 +94,7 @@ class _PagesPanelState extends State { _scrollController.jumpTo(currentIndex * 56); }); return Container( - height: widget.sheetHeight, + height: context.height.abs() * 0.7, color: Theme.of(context).colorScheme.background, child: Column( children: [ diff --git a/lib/pages/video/detail/introduction/widgets/season.dart b/lib/pages/video/detail/introduction/widgets/season.dart index 9b21f5213..ad62ee016 100644 --- a/lib/pages/video/detail/introduction/widgets/season.dart +++ b/lib/pages/video/detail/introduction/widgets/season.dart @@ -10,12 +10,10 @@ class SeasonPanel extends StatefulWidget { super.key, required this.ugcSeason, this.cid, - this.sheetHeight, this.changeFuc, }); final UgcSeason ugcSeason; final int? cid; - final double? sheetHeight; final Function? changeFuc; @override @@ -104,7 +102,7 @@ class _SeasonPanelState extends State { itemScrollController.jumpTo(index: currentIndex); }); return Container( - height: widget.sheetHeight, + height: context.height.abs() * 0.7, color: Theme.of(context).colorScheme.background, child: Column( children: [ diff --git a/lib/pages/video/detail/reply_reply/view.dart b/lib/pages/video/detail/reply_reply/view.dart index c08c81cce..67ae59f73 100644 --- a/lib/pages/video/detail/reply_reply/view.dart +++ b/lib/pages/video/detail/reply_reply/view.dart @@ -1,13 +1,11 @@ import 'package:easy_debounce/easy_throttle.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:hive/hive.dart'; import 'package:pilipala/common/skeleton/video_reply.dart'; import 'package:pilipala/common/widgets/http_error.dart'; import 'package:pilipala/models/common/reply_type.dart'; import 'package:pilipala/models/video/reply/item.dart'; import 'package:pilipala/pages/video/detail/reply/widgets/reply_item.dart'; -import 'package:pilipala/utils/storage.dart'; import 'controller.dart'; @@ -35,8 +33,6 @@ class VideoReplyReplyPanel extends StatefulWidget { class _VideoReplyReplyPanelState extends State { late VideoReplyReplyController _videoReplyReplyController; late AnimationController replyAnimationCtl; - final Box localCache = GStrorage.localCache; - late double sheetHeight; Future? _futureBuilderFuture; late ScrollController scrollController; @@ -61,7 +57,6 @@ class _VideoReplyReplyPanelState extends State { }, ); - sheetHeight = localCache.get('sheetHeight'); _futureBuilderFuture = _videoReplyReplyController.queryReplyList(); } @@ -76,7 +71,7 @@ class _VideoReplyReplyPanelState extends State { @override Widget build(BuildContext context) { return Container( - height: widget.source == 'videoDetail' ? sheetHeight : null, + height: widget.source == 'videoDetail' ? context.height.abs() * 0.7 : null, color: Theme.of(context).colorScheme.background, child: Column( children: [ diff --git a/lib/pages/video/detail/view.dart b/lib/pages/video/detail/view.dart index 320a3c8a4..167ac707d 100644 --- a/lib/pages/video/detail/view.dart +++ b/lib/pages/video/detail/view.dart @@ -63,6 +63,7 @@ class _VideoDetailPageState extends State // 生命周期监听 late final AppLifecycleListener _lifecycleListener; bool isShowing = true; + bool isFullScreen = false; @override void initState() { @@ -91,7 +92,8 @@ class _VideoDetailPageState extends State autoPlayEnable = setting.get(SettingBoxKey.autoPlayEnable, defaultValue: true); autoPiP = setting.get(SettingBoxKey.autoPiP, defaultValue: false); - + videoDetailController + .setTriggerFullScreenCallback(triggerFullScreenCallback); videoSourceInit(); appbarStreamListen(); lifecycleListener(); @@ -163,6 +165,8 @@ class _VideoDetailPageState extends State /// 未开启自动播放时触发播放 Future handlePlay() async { + videoDetailController + .setTriggerFullScreenCallback(triggerFullScreenCallback); await videoDetailController.playerInit(); plPlayerController = videoDetailController.plPlayerController; plPlayerController!.addStatusLister(playerListener); @@ -231,6 +235,8 @@ class _VideoDetailPageState extends State setState(() => isShowing = true); videoDetailController.isFirstTime = false; final bool autoplay = autoPlayEnable; + videoDetailController + .setTriggerFullScreenCallback(triggerFullScreenCallback); videoDetailController.playerInit(autoplay: autoplay); /// 未开启自动播放时,未播放跳转下一页返回/播放后跳转下一页返回 @@ -279,6 +285,13 @@ class _VideoDetailPageState extends State } } + void triggerFullScreenCallback({bool? status}) { + SmartDialog.showToast('triggerFullScreen $status $isFullScreen'); + setState(() { + isFullScreen = status ?? !isFullScreen; + }); + } + @override Widget build(BuildContext context) { final double videoHeight = MediaQuery.sizeOf(context).width * 9 / 16; @@ -286,11 +299,11 @@ class _VideoDetailPageState extends State statusBarHeight + kToolbarHeight + videoHeight; Widget childWhenDisabled = SafeArea( top: MediaQuery.of(context).orientation == Orientation.portrait && - plPlayerController?.isFullScreen.value == true, + isFullScreen == true, bottom: MediaQuery.of(context).orientation == Orientation.portrait && - plPlayerController?.isFullScreen.value == true, - left: false, //plPlayerController?.isFullScreen.value != true, - right: false, //plPlayerController?.isFullScreen.value != true, + isFullScreen == true, + left: false, //isFullScreen != true, + right: false, //isFullScreen != true, child: Stack( children: [ Scaffold( @@ -313,7 +326,7 @@ class _VideoDetailPageState extends State () { if (MediaQuery.of(context).orientation == Orientation.landscape || - plPlayerController?.isFullScreen.value == true) { + isFullScreen == true) { enterFullScreen(); } else { exitFullScreen(); @@ -329,7 +342,7 @@ class _VideoDetailPageState extends State forceElevated: innerBoxIsScrolled, expandedHeight: MediaQuery.of(context).orientation == Orientation.landscape || - plPlayerController?.isFullScreen.value == true + isFullScreen == true ? MediaQuery.sizeOf(context).height - (MediaQuery.of(context).orientation == Orientation.landscape @@ -339,11 +352,9 @@ class _VideoDetailPageState extends State backgroundColor: Colors.black, flexibleSpace: FlexibleSpaceBar( background: PopScope( - canPop: plPlayerController?.isFullScreen.value != - true, + canPop: isFullScreen != true, onPopInvoked: (bool didPop) { - if (plPlayerController?.isFullScreen.value == - true) { + if (isFullScreen == true) { plPlayerController! .triggerFullScreen(status: false); } @@ -501,9 +512,12 @@ class _VideoDetailPageState extends State // }, /// 不收回 pinnedHeaderSliverHeightBuilder: () { + if (playerStatus != PlayerStatus.playing) { + return 0; + } return MediaQuery.of(context).orientation == Orientation.landscape || - plPlayerController?.isFullScreen.value == true + isFullScreen == true ? MediaQuery.sizeOf(context).height : pinnedHeaderHeight; }, @@ -603,6 +617,213 @@ class _VideoDetailPageState extends State ], ), ); + + Widget childWhenDisabledLandscape = SafeArea( + left: isFullScreen != true, + right: isFullScreen != true, + child: Stack(children: [ + Scaffold( + resizeToAvoidBottomInset: false, + key: videoDetailController.scaffoldKey, + backgroundColor: Theme.of(context).colorScheme.background, + appBar: PreferredSize( + preferredSize: const Size.fromHeight(0), + child: AppBar( + backgroundColor: Colors.transparent, + elevation: 0, + ), + ), + body: Row( + children: [ + Column( + children: [ + SizedBox( + width: isFullScreen == true + ? Get.width + : Get.height * 0.6 * 16 / 9, + height: isFullScreen == true + ? Get.height + : Get.height * 0.6, + child: PopScope( + canPop: isFullScreen != true, + onPopInvoked: (bool didPop) { + if (isFullScreen == true) { + plPlayerController! + .triggerFullScreen(status: false); + } + if (MediaQuery.of(context).orientation == + Orientation.landscape && + exitFullscreenAutoVertical) { + verticalScreen(); + } + }, + child: LayoutBuilder( + builder: (BuildContext context, + BoxConstraints boxConstraints) { + final double maxWidth = + boxConstraints.maxWidth / 2; + final double maxHeight = + boxConstraints.maxHeight / 2; + return Stack( + children: [ + if (isShowing) + Obx( + () => !videoDetailController + .autoPlay.value || + plPlayerController + ?.videoController == + null + ? nil + : PLVideoPlayer( + controller: + plPlayerController!, + headerControl: + videoDetailController + .headerControl, + danmuWidget: Obx( + () => PlDanmaku( + key: Key( + videoDetailController + .danmakuCid.value + .toString()), + cid: videoDetailController + .danmakuCid.value, + playerController: + plPlayerController!, + ), + ), + ), + ), + + /// 关闭自动播放时 手动播放 + if (!videoDetailController + .autoPlay.value) ...[ + Obx( + () => Visibility( + visible: videoDetailController + .isShowCover.value, + child: Positioned( + top: 0, + left: 0, + right: 0, + child: GestureDetector( + onTap: () { + handlePlay(); + }, + child: NetworkImgLayer( + type: 'emote', + src: videoDetailController + .videoItem['pic'], + width: maxWidth, + height: maxHeight, + ), + ), + ), + ), + ), + Obx( + () => Visibility( + visible: videoDetailController + .isShowCover.value && + videoDetailController + .isEffective.value, + child: Stack( + children: [ + Positioned( + top: 0, + left: 0, + right: 0, + child: AppBar( + primary: false, + foregroundColor: + Colors.white, + elevation: 0, + scrolledUnderElevation: 0, + backgroundColor: + Colors.transparent, + actions: [ + IconButton( + tooltip: '稍后再看', + onPressed: () async { + var res = await UserHttp + .toViewLater( + bvid: videoDetailController + .bvid); + SmartDialog + .showToast( + res['msg']); + }, + icon: const Icon(Icons + .history_outlined), + ), + const SizedBox( + width: 14) + ], + ), + ), + Positioned( + right: 12, + bottom: 10, + child: IconButton( + tooltip: '播放', + onPressed: () => + handlePlay(), + icon: Image.asset( + 'assets/images/play.png', + width: 60, + height: 60, + )), + ), + ], + )), + ), + ] + ], + ); + }, + ))), + SizedBox( + width: isFullScreen == true + ? Get.width + : Get.height * 0.6 * 16 / 9, + height: isFullScreen == true ? 0 : Get.height * 0.4, + child: (videoDetailController.videoType == + SearchType.video) + ? const CustomScrollView( + slivers: [VideoIntroPanel()]) + : (videoDetailController.videoType == + SearchType.media_bangumi) + ? Obx(() => BangumiIntroPanel( + cid: videoDetailController.cid.value)) + : const SizedBox(), + ) + ], + ), + SizedBox( + width: isFullScreen == true + ? 0 + : (Get.width - + MediaQuery.of(context).padding.left - + MediaQuery.of(context).padding.right - + Get.height * 0.6 * 16 / 9), + height: Get.height, + child: TabBarView( + controller: videoDetailController.tabCtr, + children: [ + CustomScrollView( + slivers: [ + RelatedVideoPanel(), + ], + ), + VideoReplyPanel( + bvid: videoDetailController.bvid, + ) + ], + ), + ) + ], + )) + ])); Widget childWhenEnabled = FutureBuilder( key: Key(heroTag), future: _futureBuilderFuture, @@ -632,14 +853,25 @@ class _VideoDetailPageState extends State } }, ); - if (Platform.isAndroid) { - return PiPSwitcher( - childWhenDisabled: childWhenDisabled, - childWhenEnabled: childWhenEnabled, - floating: floating, - ); - } else { - return childWhenDisabled; - } + return OrientationBuilder( + builder: (BuildContext context, Orientation orientation) { + print("orientation:$orientation"); + if (orientation == Orientation.portrait || isFullScreen == true) { + // 竖屏 + return childWhenDisabled; + } else { + enterFullScreen(); + return childWhenDisabledLandscape; + } + }); + // if (Platform.isAndroid) { + // return PiPSwitcher( + // childWhenDisabled: childWhenDisabled, + // childWhenEnabled: childWhenEnabled, + // floating: floating, + // ); + // } else { + // return childWhenDisabled; + // } } } diff --git a/lib/pages/video/detail/widgets/ai_detail.dart b/lib/pages/video/detail/widgets/ai_detail.dart index fb280d91b..0a00d14a7 100644 --- a/lib/pages/video/detail/widgets/ai_detail.dart +++ b/lib/pages/video/detail/widgets/ai_detail.dart @@ -2,14 +2,10 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; -import 'package:hive/hive.dart'; import 'package:pilipala/models/video/ai.dart'; import 'package:pilipala/pages/video/detail/index.dart'; -import 'package:pilipala/utils/storage.dart'; import 'package:pilipala/utils/utils.dart'; -Box localCache = GStrorage.localCache; -late double sheetHeight; class AiDetail extends StatelessWidget { final ModelResult? modelResult; @@ -21,11 +17,10 @@ class AiDetail extends StatelessWidget { @override Widget build(BuildContext context) { - sheetHeight = localCache.get('sheetHeight'); return Container( color: Theme.of(context).colorScheme.background, padding: const EdgeInsets.only(left: 14, right: 14), - height: sheetHeight, + height: context.height.abs() * 0.7, child: Column( children: [ InkWell( diff --git a/lib/plugin/pl_player/controller.dart b/lib/plugin/pl_player/controller.dart index b5273c288..527f27103 100644 --- a/lib/plugin/pl_player/controller.dart +++ b/lib/plugin/pl_player/controller.dart @@ -31,6 +31,7 @@ Box localCache = GStrorage.localCache; class PlPlayerController { Player? _videoPlayerController; VideoController? _videoController; + void Function({bool? status})? triggerFullscreenCallback; // 添加一个私有静态变量来保存实例 static PlPlayerController? _instance; @@ -232,6 +233,11 @@ class PlPlayerController { // 播放顺序相关 PlayRepeat playRepeat = PlayRepeat.pause; + void setTriggerFullscreenCallback( + void Function({bool? status}) triggerFullscreenCallback) { + this.triggerFullscreenCallback = triggerFullscreenCallback; + } + void updateSliderPositionSecond() { int newSecond = _sliderPosition.value.inSeconds; if (sliderPositionSeconds.value != newSecond) { @@ -1001,6 +1007,9 @@ class PlPlayerController { } toggleFullScreen(false); } + if (triggerFullscreenCallback != null) { + triggerFullscreenCallback!(status: status); + } } void addPositionListener(Function(Duration position) listener) => diff --git a/lib/plugin/pl_player/view.dart b/lib/plugin/pl_player/view.dart index dea7c5c0b..34a1cdedc 100644 --- a/lib/plugin/pl_player/view.dart +++ b/lib/plugin/pl_player/view.dart @@ -48,6 +48,7 @@ class _PLVideoPlayerState extends State late VideoController videoController; final PLVideoPlayerController _ctr = Get.put(PLVideoPlayerController()); + final GlobalKey _playerKey = GlobalKey(); // bool _mountSeekBackwardButton = false; // bool _mountSeekForwardButton = false; // bool _hideSeekBackwardButton = false; @@ -72,7 +73,6 @@ class _PLVideoPlayerState extends State late int defaultBtmProgressBehavior; late bool enableQuickDouble; late bool enableBackgroundPlay; - late double screenWidth; // 用于记录上一次全屏切换手势触发时间,避免误触 DateTime? lastFullScreenToggleTime; @@ -116,7 +116,6 @@ class _PLVideoPlayerState extends State @override void initState() { super.initState(); - screenWidth = Get.size.width; animationController = AnimationController( vsync: this, duration: const Duration(milliseconds: 300)); videoController = widget.controller.videoController!; @@ -210,6 +209,7 @@ class _PLVideoPlayerState extends State ); return Stack( fit: StackFit.passthrough, + key: _playerKey, children: [ Obx( () => Video( @@ -445,7 +445,8 @@ class _PLVideoPlayerState extends State if (_.videoType.value == 'live' || _.controlsLock.value) { return; } - final double totalWidth = MediaQuery.sizeOf(context).width; + RenderBox renderBox = _playerKey.currentContext!.findRenderObject() as RenderBox; + final double totalWidth = renderBox.size.width; final double tapPosition = details.localPosition.dx; final double sectionWidth = totalWidth / 3; String type = 'left'; @@ -475,7 +476,8 @@ class _PLVideoPlayerState extends State // final double tapPosition = details.localPosition.dx; final int curSliderPosition = _.sliderPosition.value.inMilliseconds; - final double scale = 90000 / MediaQuery.sizeOf(context).width; + RenderBox renderBox = _playerKey.currentContext!.findRenderObject() as RenderBox; + final double scale = 90000 / renderBox.size.width; final Duration pos = Duration( milliseconds: curSliderPosition + (details.delta.dx * scale).round()); @@ -494,7 +496,8 @@ class _PLVideoPlayerState extends State }, // 垂直方向 音量/亮度调节 onVerticalDragUpdate: (DragUpdateDetails details) async { - final double totalWidth = MediaQuery.sizeOf(context).width; + RenderBox renderBox = _playerKey.currentContext!.findRenderObject() as RenderBox; + final double totalWidth = renderBox.size.width; final double tapPosition = details.localPosition.dx; final double sectionWidth = totalWidth / 3; final double delta = details.delta.dy; @@ -510,10 +513,7 @@ class _PLVideoPlayerState extends State } if (tapPosition < sectionWidth) { // 左边区域 👈 - final double level = (_.isFullScreen.value - ? Get.size.height - : screenWidth * 9 / 16) * - 3; + final double level = renderBox.size.height * 3; final double brightness = _ctr.brightnessValue.value - delta / level; final double result = brightness.clamp(0.0, 1.0); @@ -540,10 +540,7 @@ class _PLVideoPlayerState extends State _distance = dy; } else { // 右边区域 👈 - final double level = (_.isFullScreen.value - ? Get.size.height - : screenWidth * 9 / 16) * - 0.5; + final double level = renderBox.size.height * 0.5; if(lastVolume < 0) { lastVolume = _ctr.volumeValue.value; } @@ -761,11 +758,12 @@ class _PLVideoPlayerState extends State ) : nil, ), - Expanded( - child: SizedBox( - width: MediaQuery.sizeOf(context).width / 4, - ), - ), + const Spacer(), + // Expanded( + // child: SizedBox( + // width: context.width / 4, + // ), + // ), Expanded( child: _ctr.mountSeekForwardButton.value ? TweenAnimationBuilder( diff --git a/lib/plugin/pl_player/widgets/bottom_control.dart b/lib/plugin/pl_player/widgets/bottom_control.dart index 8f21fc175..7105c82f5 100644 --- a/lib/plugin/pl_player/widgets/bottom_control.dart +++ b/lib/plugin/pl_player/widgets/bottom_control.dart @@ -146,7 +146,7 @@ class BottomControl extends StatelessWidget implements PreferredSizeWidget { size: 15, color: Colors.white, ), - fuc: () => triggerFullScreen!(), + fuc: () => triggerFullScreen!(status: !_.isFullScreen.value), ), ), ],