Merge branch 'main' into design
This commit is contained in:
@ -45,25 +45,37 @@ class EpisodeBottomSheet {
|
||||
title = '第${episode.title}话 ${episode.longTitle!}';
|
||||
break;
|
||||
}
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
SmartDialog.showToast('切换至「$title」');
|
||||
changeFucCall.call(episode, index);
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 14, right: 14, top: 8, bottom: 8),
|
||||
child: isFullScreen
|
||||
? Text(
|
||||
title,
|
||||
maxLines: 1,
|
||||
return isFullScreen || episode?.cover == null || episode?.cover == ''
|
||||
? ListTile(
|
||||
onTap: () {
|
||||
SmartDialog.showToast('切换至「$title」');
|
||||
changeFucCall.call(episode, index);
|
||||
},
|
||||
dense: false,
|
||||
leading: isCurrentIndex
|
||||
? Image.asset(
|
||||
'assets/images/live.gif',
|
||||
color: primary,
|
||||
height: 12,
|
||||
)
|
||||
: null,
|
||||
title: Text(title,
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: isCurrentIndex ? primary : onSurface,
|
||||
),
|
||||
)
|
||||
: Row(
|
||||
)))
|
||||
: InkWell(
|
||||
onTap: () {
|
||||
SmartDialog.showToast('切换至「$title」');
|
||||
changeFucCall.call(episode, index);
|
||||
},
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 14, right: 14, top: 8, bottom: 8),
|
||||
child: Row(
|
||||
children: [
|
||||
NetworkImgLayer(width: 130, height: 75, src: episode.cover),
|
||||
NetworkImgLayer(
|
||||
width: 130, height: 75, src: episode?.cover ?? ''),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Text(
|
||||
@ -77,8 +89,8 @@ class EpisodeBottomSheet {
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildTitle() {
|
||||
|
@ -65,6 +65,20 @@ void main() async {
|
||||
},
|
||||
);
|
||||
|
||||
// 小白条、导航栏沉浸
|
||||
if (Platform.isAndroid) {
|
||||
List<String> versionParts = Platform.version.split('.');
|
||||
int androidVersion = int.parse(versionParts[0]);
|
||||
if (androidVersion >= 29) {
|
||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
|
||||
}
|
||||
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
|
||||
systemNavigationBarColor: Colors.transparent,
|
||||
systemNavigationBarDividerColor: Colors.transparent,
|
||||
statusBarColor: Colors.transparent,
|
||||
));
|
||||
}
|
||||
|
||||
Data.init();
|
||||
GlobalData();
|
||||
PiliSchame.init();
|
||||
@ -130,26 +144,33 @@ class MyApp extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
ThemeData themeData = ThemeData(
|
||||
colorScheme: currentThemeValue == ThemeType.dark
|
||||
? darkColorScheme
|
||||
: lightColorScheme,
|
||||
);
|
||||
// ThemeData themeData = ThemeData(
|
||||
// colorScheme: currentThemeValue == ThemeType.dark
|
||||
// ? darkColorScheme
|
||||
// : lightColorScheme,
|
||||
// );
|
||||
|
||||
// 小白条、导航栏沉浸
|
||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
|
||||
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
|
||||
systemNavigationBarColor: GlobalData().enableMYBar
|
||||
? const Color(0x00010000)
|
||||
: themeData.canvasColor,
|
||||
systemNavigationBarDividerColor: GlobalData().enableMYBar
|
||||
? const Color(0x00010000)
|
||||
: themeData.canvasColor,
|
||||
systemNavigationBarIconBrightness: currentThemeValue == ThemeType.dark
|
||||
? Brightness.light
|
||||
: Brightness.dark,
|
||||
statusBarColor: Colors.transparent,
|
||||
));
|
||||
// // 小白条、导航栏沉浸
|
||||
// if (Platform.isAndroid) {
|
||||
// List<String> versionParts = Platform.version.split('.');
|
||||
// int androidVersion = int.parse(versionParts[0]);
|
||||
// if (androidVersion >= 29) {
|
||||
// SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
|
||||
// }
|
||||
// SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
|
||||
// systemNavigationBarColor: GlobalData().enableMYBar
|
||||
// ? const Color(0x00010000)
|
||||
// : themeData.canvasColor,
|
||||
// systemNavigationBarDividerColor: GlobalData().enableMYBar
|
||||
// ? const Color(0x00010000)
|
||||
// : themeData.canvasColor,
|
||||
// systemNavigationBarIconBrightness:
|
||||
// currentThemeValue == ThemeType.dark
|
||||
// ? Brightness.light
|
||||
// : Brightness.dark,
|
||||
// statusBarColor: Colors.transparent,
|
||||
// ));
|
||||
// }
|
||||
|
||||
// 图片缓存
|
||||
// PaintingBinding.instance.imageCache.maximumSizeBytes = 1000 << 20;
|
||||
|
@ -412,8 +412,8 @@ class Part {
|
||||
dimension = json["dimension"] == null
|
||||
? null
|
||||
: Dimension.fromJson(json["dimension"]);
|
||||
firstFrame = json["first_frame"];
|
||||
cover = json["first_frame"];
|
||||
firstFrame = json["first_frame"] ?? '';
|
||||
cover = json["first_frame"] ?? '';
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
|
@ -115,20 +115,15 @@ class VideoDetailController extends GetxController
|
||||
super.onInit();
|
||||
final Map argMap = Get.arguments;
|
||||
userInfo = userInfoCache.get('userInfoCache');
|
||||
var keys = argMap.keys.toList();
|
||||
if (keys.isNotEmpty) {
|
||||
if (keys.contains('videoItem')) {
|
||||
var args = argMap['videoItem'];
|
||||
if (args.pic != null && args.pic != '') {
|
||||
videoItem['pic'] = args.pic;
|
||||
cover.value = args.pic;
|
||||
}
|
||||
}
|
||||
if (keys.contains('pic')) {
|
||||
videoItem['pic'] = argMap['pic'];
|
||||
cover.value = argMap['pic'];
|
||||
}
|
||||
if (argMap.containsKey('videoItem')) {
|
||||
var args = argMap['videoItem'];
|
||||
updateCover(args.pic);
|
||||
}
|
||||
|
||||
if (argMap.containsKey('pic')) {
|
||||
updateCover(argMap['pic']);
|
||||
}
|
||||
|
||||
tabCtr = TabController(length: 2, vsync: this);
|
||||
autoPlay.value =
|
||||
setting.get(SettingBoxKey.autoPlayEnable, defaultValue: true);
|
||||
@ -550,4 +545,10 @@ class VideoDetailController extends GetxController
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void updateCover(String? pic) {
|
||||
if (pic != null && pic != '') {
|
||||
cover.value = videoItem['pic'] = pic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,6 +90,7 @@ class VideoIntroController extends GetxController {
|
||||
final VideoDetailController videoDetailCtr =
|
||||
Get.find<VideoDetailController>(tag: heroTag);
|
||||
videoDetailCtr.tabs.value = ['简介', '评论 ${result['data']?.stat?.reply}'];
|
||||
videoDetailCtr.cover.value = result['data'].pic ?? '';
|
||||
// 获取到粉丝数再返回
|
||||
await queryUserStat();
|
||||
}
|
||||
|
@ -135,7 +135,6 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
late double sheetHeight;
|
||||
late final dynamic owner;
|
||||
late final dynamic follower;
|
||||
late final dynamic followStatus;
|
||||
late int mid;
|
||||
late String memberHeroTag;
|
||||
late bool enableAi;
|
||||
@ -164,7 +163,6 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
|
||||
owner = widget.videoDetail!.owner;
|
||||
follower = Utils.numFormat(videoIntroController.userStat['follower']);
|
||||
followStatus = videoIntroController.followStatus;
|
||||
enableAi = setting.get(SettingBoxKey.enableAi, defaultValue: true);
|
||||
_expandableCtr = ExpandableController(initialExpanded: false);
|
||||
}
|
||||
@ -441,48 +439,39 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
|
||||
),
|
||||
const Spacer(),
|
||||
Obx(
|
||||
() => AnimatedOpacity(
|
||||
opacity:
|
||||
videoIntroController.followStatus.isEmpty ? 0 : 1,
|
||||
duration: const Duration(milliseconds: 50),
|
||||
child: SizedBox(
|
||||
height: 32,
|
||||
child: Obx(
|
||||
() => videoIntroController.followStatus.isNotEmpty
|
||||
? TextButton(
|
||||
onPressed:
|
||||
videoIntroController.actionRelationMod,
|
||||
style: TextButton.styleFrom(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 8, right: 8),
|
||||
foregroundColor:
|
||||
followStatus['attribute'] != 0
|
||||
? outline
|
||||
: t.colorScheme.onPrimary,
|
||||
backgroundColor:
|
||||
followStatus['attribute'] != 0
|
||||
? t.colorScheme.onInverseSurface
|
||||
: t.colorScheme
|
||||
.primary, // 设置按钮背景色
|
||||
() {
|
||||
final bool isFollowed =
|
||||
videoIntroController.followStatus['attribute'] != 0;
|
||||
return videoIntroController.followStatus.isEmpty
|
||||
? const SizedBox()
|
||||
: SizedBox(
|
||||
height: 32,
|
||||
child: TextButton(
|
||||
onPressed:
|
||||
videoIntroController.actionRelationMod,
|
||||
style: TextButton.styleFrom(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 8,
|
||||
right: 8,
|
||||
),
|
||||
child: Text(
|
||||
followStatus['attribute'] != 0
|
||||
? '已关注'
|
||||
: '关注',
|
||||
style: TextStyle(
|
||||
fontSize: t
|
||||
.textTheme.labelMedium!.fontSize),
|
||||
),
|
||||
)
|
||||
: ElevatedButton(
|
||||
onPressed:
|
||||
videoIntroController.actionRelationMod,
|
||||
child: const Text('关注'),
|
||||
foregroundColor: isFollowed
|
||||
? outline
|
||||
: t.colorScheme.onPrimary,
|
||||
backgroundColor: isFollowed
|
||||
? t.colorScheme.onInverseSurface
|
||||
: t.colorScheme.primary, // 设置按钮背景色
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
isFollowed ? '已关注' : '关注',
|
||||
style: TextStyle(
|
||||
fontSize:
|
||||
t.textTheme.labelMedium!.fontSize,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -427,7 +427,7 @@ class ReplyItemRow extends StatelessWidget {
|
||||
if (extraRow == 1)
|
||||
InkWell(
|
||||
// 一楼点击【共xx条回复】展开评论详情
|
||||
onTap: () => replyReply!(replyItem, null),
|
||||
onTap: () => replyReply!(replyItem),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.fromLTRB(8, 5, 8, 8),
|
||||
|
@ -23,6 +23,7 @@ import 'package:pilipala/plugin/pl_player/index.dart';
|
||||
import 'package:pilipala/plugin/pl_player/models/play_repeat.dart';
|
||||
import 'package:pilipala/services/service_locator.dart';
|
||||
import 'package:pilipala/utils/storage.dart';
|
||||
import 'package:status_bar_control/status_bar_control.dart';
|
||||
|
||||
import '../../../plugin/pl_player/models/bottom_control_type.dart';
|
||||
import '../../../services/shutdown_timer_service.dart';
|
||||
@ -38,7 +39,7 @@ class VideoDetailPage extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
with TickerProviderStateMixin, RouteAware {
|
||||
with TickerProviderStateMixin, RouteAware, WidgetsBindingObserver {
|
||||
late VideoDetailController vdCtr;
|
||||
PlPlayerController? plPlayerController;
|
||||
final ScrollController _extendNestCtr = ScrollController();
|
||||
@ -61,10 +62,14 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
late bool autoPiP;
|
||||
late Floating floating;
|
||||
bool isShowing = true;
|
||||
// 生命周期监听
|
||||
late final AppLifecycleListener _lifecycleListener;
|
||||
late double statusHeight;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
getStatusHeight();
|
||||
heroTag = Get.arguments['heroTag'];
|
||||
vdCtr = Get.put(VideoDetailController(), tag: heroTag);
|
||||
vdCtr.sheetHeight.value = localCache.get('sheetHeight');
|
||||
@ -96,6 +101,8 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
floating = vdCtr.floating!;
|
||||
autoEnterPip();
|
||||
}
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
lifecycleListener();
|
||||
}
|
||||
|
||||
// 获取视频资源,初始化播放器
|
||||
@ -203,6 +210,10 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
});
|
||||
}
|
||||
|
||||
getStatusHeight() async {
|
||||
statusHeight = await StatusBarControl.getHeight;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
shutdownTimerService.handleWaitingFinished();
|
||||
@ -219,6 +230,8 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
floating.dispose();
|
||||
}
|
||||
appbarStream.close();
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
_lifecycleListener.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@ -281,6 +294,166 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
}
|
||||
}
|
||||
|
||||
// 生命周期监听
|
||||
void lifecycleListener() {
|
||||
_lifecycleListener = AppLifecycleListener(
|
||||
// onResume: () => _handleTransition('resume'),
|
||||
// 后台
|
||||
// onInactive: () => _handleTransition('inactive'),
|
||||
// 在Android和iOS端不生效
|
||||
// onHide: () => _handleTransition('hide'),
|
||||
onShow: () => _handleTransition('show'),
|
||||
onPause: () => _handleTransition('pause'),
|
||||
onRestart: () => _handleTransition('restart'),
|
||||
onDetach: () => _handleTransition('detach'),
|
||||
);
|
||||
}
|
||||
|
||||
void _handleTransition(String name) {
|
||||
switch (name) {
|
||||
case 'show' || 'restart':
|
||||
plPlayerController?.danmakuController?.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// 手动播放
|
||||
Widget handlePlayPanel() {
|
||||
return Stack(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: handlePlay,
|
||||
child: Image.network(
|
||||
vdCtr.videoItem['pic'],
|
||||
width: Get.width,
|
||||
height: videoHeight,
|
||||
fit: BoxFit.cover, // 适应方式根据需要调整
|
||||
),
|
||||
),
|
||||
buildCustomAppBar(),
|
||||
Positioned(
|
||||
right: 12,
|
||||
bottom: 10,
|
||||
child: GestureDetector(
|
||||
onTap: handlePlay,
|
||||
child: Image.asset(
|
||||
'assets/images/play.png',
|
||||
width: 60,
|
||||
height: 60,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/// tabbar
|
||||
Widget tabbarBuild() {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
height: 45,
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
width: 1,
|
||||
color: Theme.of(context).dividerColor.withOpacity(0.1),
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Material(
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Obx(
|
||||
() => TabBar(
|
||||
padding: EdgeInsets.zero,
|
||||
controller: vdCtr.tabCtr,
|
||||
labelStyle: const TextStyle(fontSize: 13),
|
||||
labelPadding: const EdgeInsets.symmetric(horizontal: 10.0),
|
||||
dividerColor: Colors.transparent,
|
||||
tabs:
|
||||
vdCtr.tabs.map((String name) => Tab(text: name)).toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: Center(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Obx(() => AnimatedOpacity(
|
||||
opacity: playerStatus.value != PlayerStatus.playing
|
||||
? 1
|
||||
: 0,
|
||||
duration: const Duration(milliseconds: 100),
|
||||
child: const Icon(
|
||||
Icons.drag_handle_rounded,
|
||||
size: 20,
|
||||
color: Colors.grey,
|
||||
),
|
||||
)),
|
||||
const SizedBox(width: 8),
|
||||
SizedBox(
|
||||
height: 32,
|
||||
child: TextButton(
|
||||
style: ButtonStyle(
|
||||
padding: MaterialStateProperty.all(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: () => vdCtr.showShootDanmakuSheet(),
|
||||
child:
|
||||
const Text('发弹幕', style: TextStyle(fontSize: 12)),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 38,
|
||||
height: 38,
|
||||
child: Obx(
|
||||
() => !vdCtr.isShowCover.value
|
||||
? IconButton(
|
||||
onPressed: () {
|
||||
plPlayerController?.isOpenDanmu.value =
|
||||
!(plPlayerController?.isOpenDanmu.value ??
|
||||
false);
|
||||
},
|
||||
icon: !(plPlayerController?.isOpenDanmu.value ??
|
||||
false)
|
||||
? SvgPicture.asset(
|
||||
'assets/images/video/danmu_close.svg',
|
||||
// ignore: deprecated_member_use
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.outline,
|
||||
)
|
||||
: SvgPicture.asset(
|
||||
'assets/images/video/danmu_open.svg',
|
||||
// ignore: deprecated_member_use
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.primary,
|
||||
),
|
||||
)
|
||||
: IconButton(
|
||||
icon: SvgPicture.asset(
|
||||
'assets/images/video/danmu_close.svg',
|
||||
// ignore: deprecated_member_use
|
||||
color: Theme.of(context).colorScheme.outline,
|
||||
),
|
||||
onPressed: () {},
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 18),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final sizeContext = MediaQuery.sizeOf(context);
|
||||
@ -338,168 +511,13 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
},
|
||||
);
|
||||
|
||||
/// tabbar
|
||||
Widget tabbarBuild = Container(
|
||||
width: double.infinity,
|
||||
height: 45,
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
width: 1,
|
||||
color: Theme.of(context).dividerColor.withOpacity(0.1),
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Material(
|
||||
child: Row(
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: Obx(
|
||||
() => TabBar(
|
||||
padding: EdgeInsets.zero,
|
||||
controller: vdCtr.tabCtr,
|
||||
labelStyle: const TextStyle(fontSize: 13),
|
||||
labelPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 10.0), // 设置每个标签的宽度
|
||||
dividerColor: Colors.transparent,
|
||||
tabs: vdCtr.tabs
|
||||
.map(
|
||||
(String name) => Tab(text: name),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: Center(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Obx(() => AnimatedOpacity(
|
||||
opacity: playerStatus.value != PlayerStatus.playing
|
||||
? 1
|
||||
: 0,
|
||||
duration: const Duration(milliseconds: 100),
|
||||
child: const Icon(
|
||||
Icons.drag_handle_rounded,
|
||||
size: 20,
|
||||
color: Colors.grey,
|
||||
),
|
||||
)),
|
||||
const SizedBox(width: 8),
|
||||
SizedBox(
|
||||
height: 32,
|
||||
child: TextButton(
|
||||
style: ButtonStyle(
|
||||
padding: MaterialStateProperty.all(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: () => vdCtr.showShootDanmakuSheet(),
|
||||
child:
|
||||
const Text('发弹幕', style: TextStyle(fontSize: 12)),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 38,
|
||||
height: 38,
|
||||
child: Obx(
|
||||
() => !vdCtr.isShowCover.value
|
||||
? IconButton(
|
||||
onPressed: () {
|
||||
plPlayerController?.isOpenDanmu.value =
|
||||
!(plPlayerController
|
||||
?.isOpenDanmu.value ??
|
||||
false);
|
||||
},
|
||||
icon:
|
||||
!(plPlayerController?.isOpenDanmu.value ??
|
||||
false)
|
||||
? SvgPicture.asset(
|
||||
'assets/images/video/danmu_close.svg',
|
||||
// ignore: deprecated_member_use
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.outline,
|
||||
)
|
||||
: SvgPicture.asset(
|
||||
'assets/images/video/danmu_open.svg',
|
||||
// ignore: deprecated_member_use
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.primary,
|
||||
),
|
||||
)
|
||||
: IconButton(
|
||||
icon: SvgPicture.asset(
|
||||
'assets/images/video/danmu_close.svg',
|
||||
// ignore: deprecated_member_use
|
||||
color:
|
||||
Theme.of(context).colorScheme.outline,
|
||||
),
|
||||
onPressed: () {},
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 18),
|
||||
],
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
/// 手动播放
|
||||
Widget handlePlayPanel() {
|
||||
return Stack(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
handlePlay();
|
||||
},
|
||||
child: Obx(
|
||||
() => AnimatedOpacity(
|
||||
duration: const Duration(milliseconds: 100), // 渐变动画的持续时间
|
||||
opacity: 1, // 设置不透明度
|
||||
child: NetworkImgLayer(
|
||||
type: 'emote',
|
||||
src: vdCtr.cover.value,
|
||||
width: Get.width,
|
||||
height: videoHeight.value,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: buildCustomAppBar(),
|
||||
),
|
||||
Positioned(
|
||||
right: 12,
|
||||
bottom: 10,
|
||||
child: IconButton(
|
||||
tooltip: '播放',
|
||||
onPressed: () => handlePlay(),
|
||||
icon: Image.asset(
|
||||
'assets/images/play.png',
|
||||
width: 60,
|
||||
height: 60,
|
||||
)),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget childWhenDisabled = SafeArea(
|
||||
top: MediaQuery.of(context).orientation == Orientation.portrait &&
|
||||
plPlayerController?.isFullScreen.value == true,
|
||||
bottom: MediaQuery.of(context).orientation == Orientation.portrait &&
|
||||
plPlayerController?.isFullScreen.value == true,
|
||||
left: false, //plPlayerController?.isFullScreen.value != true,
|
||||
right: false, //plPlayerController?.isFullScreen.value != true,
|
||||
left: false,
|
||||
right: false,
|
||||
child: Stack(
|
||||
children: [
|
||||
Scaffold(
|
||||
@ -517,12 +535,22 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
controller: _extendNestCtr,
|
||||
headerSliverBuilder:
|
||||
(BuildContext context2, bool innerBoxIsScrolled) {
|
||||
final Orientation orientation =
|
||||
MediaQuery.of(context).orientation;
|
||||
final bool isFullScreen =
|
||||
plPlayerController?.isFullScreen.value == true;
|
||||
final double expandedHeight =
|
||||
orientation == Orientation.landscape || isFullScreen
|
||||
? (MediaQuery.sizeOf(context).height -
|
||||
(orientation == Orientation.landscape
|
||||
? 0
|
||||
: MediaQuery.of(context).padding.top))
|
||||
: videoHeight.value;
|
||||
return <Widget>[
|
||||
Obx(
|
||||
() {
|
||||
if (MediaQuery.of(context).orientation ==
|
||||
Orientation.landscape ||
|
||||
plPlayerController?.isFullScreen.value == true) {
|
||||
if (orientation == Orientation.landscape ||
|
||||
isFullScreen) {
|
||||
enterFullScreen();
|
||||
} else {
|
||||
exitFullScreen();
|
||||
@ -534,15 +562,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0,
|
||||
forceElevated: innerBoxIsScrolled,
|
||||
expandedHeight: MediaQuery.of(context).orientation ==
|
||||
Orientation.landscape ||
|
||||
plPlayerController?.isFullScreen.value == true
|
||||
? (MediaQuery.sizeOf(context).height -
|
||||
(MediaQuery.of(context).orientation ==
|
||||
Orientation.landscape
|
||||
? 0
|
||||
: MediaQuery.of(context).padding.top))
|
||||
: videoHeight.value,
|
||||
expandedHeight: expandedHeight,
|
||||
backgroundColor: Colors.black,
|
||||
flexibleSpace: FlexibleSpaceBar(
|
||||
background: PopScope(
|
||||
@ -562,13 +582,13 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
child: LayoutBuilder(
|
||||
builder: (BuildContext context,
|
||||
BoxConstraints boxConstraints) {
|
||||
// final double maxWidth =
|
||||
// boxConstraints.maxWidth;
|
||||
// final double maxHeight =
|
||||
// boxConstraints.maxHeight;
|
||||
return Stack(
|
||||
children: <Widget>[
|
||||
if (isShowing) videoPlayerPanel,
|
||||
if (isShowing)
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 0),
|
||||
child: videoPlayerPanel,
|
||||
),
|
||||
|
||||
/// 关闭自动播放时 手动播放
|
||||
Obx(
|
||||
@ -610,7 +630,7 @@ class _VideoDetailPageState extends State<VideoDetailPage>
|
||||
color: Theme.of(context).colorScheme.background,
|
||||
child: Column(
|
||||
children: [
|
||||
tabbarBuild,
|
||||
tabbarBuild(),
|
||||
Expanded(
|
||||
child: TabBarView(
|
||||
controller: vdCtr.tabCtr,
|
||||
|
@ -117,7 +117,7 @@ class PiliSchame {
|
||||
// ignore: always_specify_types
|
||||
(e) => Get.toNamed<dynamic>('/video?bvid=$bvid&cid=$cid',
|
||||
arguments: <String, String?>{
|
||||
'pic': null,
|
||||
'pic': '',
|
||||
'heroTag': heroTag,
|
||||
}),
|
||||
);
|
||||
|
Reference in New Issue
Block a user