reduce rebuild

Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-03-17 14:38:10 +08:00
parent 8a8aa6c1e0
commit d6579b29ae
23 changed files with 254 additions and 214 deletions

View File

@@ -5,12 +5,12 @@ import 'dart:ui';
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/custom_icon.dart';
import 'package:PiliPlus/common/widgets/flutter/pop_scope.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/common/widgets/image_viewer/hero_dialog_route.dart';
import 'package:PiliPlus/common/widgets/keep_alive_wrapper.dart';
import 'package:PiliPlus/common/widgets/route_aware_mixin.dart';
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
import 'package:PiliPlus/common/widgets/sliver/sliver_pinned_dynamic_header.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/main.dart';
import 'package:PiliPlus/models/common/episode_panel_type.dart';
import 'package:PiliPlus/models_new/pgc/pgc_info_model/result.dart';
@@ -78,7 +78,11 @@ class VideoDetailPageV extends StatefulWidget {
}
class _VideoDetailPageVState extends State<VideoDetailPageV>
with TickerProviderStateMixin, RouteAware, WidgetsBindingObserver {
with
TickerProviderStateMixin,
RouteAware,
RouteAwareMixin,
WidgetsBindingObserver {
final heroTag = Get.arguments['heroTag'];
late final VideoDetailController videoDetailController;
@@ -368,7 +372,6 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
PlPlayerController.updatePlayCount();
}
}
PageUtils.routeObserver.unsubscribe(this);
WidgetsBinding.instance.removeObserver(this);
if (PlatformUtils.isMobile) {
showStatusBar();
@@ -379,10 +382,8 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
@override
// 离开当前页面时
void didPushNext() {
if (Get.routing.route is HeroDialogRoute) {
videoDetailController.imageview = true;
return;
}
super.didPushNext();
isShowing = false;
WidgetsBinding.instance.removeObserver(this);
@@ -390,11 +391,11 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
ScreenBrightnessPlatform.instance.resetApplicationScreenBrightness();
}
videoDetailController.cancelBlockListener();
introController.cancelTimer();
videoDetailController
..videoState.value = false
..cancelBlockListener()
..playerStatus = plPlayerController?.playerStatus.value
..brightness = plPlayerController?.brightness.value;
if (plPlayerController != null) {
@@ -404,21 +405,18 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
..removePositionListener(positionListener)
..pause();
}
isShowing = false;
super.didPushNext();
}
@override
// 返回当前页面时
void didPopNext() {
if (videoDetailController.imageview) {
videoDetailController.imageview = false;
super.didPopNext();
if (plPlayerController?.isCloseAll ?? false) {
return;
}
if (plPlayerController?.isCloseAll == true) {
return;
}
isShowing = true;
WidgetsBinding.instance.addObserver(this);
@@ -428,7 +426,6 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
videoDetailController.plPlayerController.pause();
}
isShowing = true;
PlPlayerController.setPlayCallBack(playCallBack);
introController.startTimer();
@@ -460,21 +457,14 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
);
} else if (videoDetailController.plPlayerController.preInitPlayer &&
!videoDetailController.isQuerying &&
videoDetailController.videoState.value is! Error) {
videoDetailController.videoUrl != null) {
videoDetailController.playerInit();
}
super.didPopNext();
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
PageUtils.routeObserver.subscribe(
this,
ModalRoute.of(context)! as PageRoute,
);
padding = MediaQuery.viewPaddingOf(context);
final size = MediaQuery.sizeOf(context);
@@ -538,9 +528,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
..addListener(animListener);
if (PlatformUtils.isMobile && mounted && isShowing && !isFullScreen) {
if (isPortrait) {
if (!videoDetailController.imageview) {
showStatusBar();
}
showStatusBar();
} else if (!videoDetailController.horizontalScreen) {
hideStatusBar();
}
@@ -1085,7 +1073,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
localIntroPanel()
else if (showIntro)
KeepAliveWrapper(
builder: (context) => CustomScrollView(
child: CustomScrollView(
key: const PageStorageKey(CommonIntroController),
controller:
videoDetailController.effectiveIntroScrollCtr,
@@ -1342,7 +1330,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
required double width,
required double height,
bool isPipMode = false,
}) => PopScope(
}) => popScope(
key: videoDetailController.videoPlayerKey,
canPop:
!isFullScreen &&
@@ -1351,7 +1339,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
onPopInvokedWithResult: _onPopInvokedWithResult,
child: Obx(
() =>
videoDetailController.videoState.value is! Success ||
!videoDetailController.videoState.value ||
!videoDetailController.autoPlay ||
plPlayerController?.videoController == null
? const SizedBox.shrink()
@@ -1589,7 +1577,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
children: [
const Positioned.fill(child: ColoredBox(color: Colors.black)),
if (isShowing) plPlayer(width: width, height: height),
plPlayer(width: width, height: height),
Obx(() {
if (!videoDetailController.autoPlay) {
@@ -1773,75 +1761,76 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
if (videoDetailController.isFileSource) {
return localIntroPanel(needCtr: needCtr);
}
Widget introPanel() => KeepAliveWrapper(
builder: (context) {
final child = CustomScrollView(
key: const PageStorageKey(CommonIntroController),
controller: needCtr
? videoDetailController.effectiveIntroScrollCtr
: null,
physics: !needCtr
? const AlwaysScrollableScrollPhysics(
parent: ClampingScrollPhysics(),
)
: null,
slivers: [
if (videoDetailController.isUgc) ...[
UgcIntroPanel(
key: videoIntroKey,
heroTag: heroTag,
showAiBottomSheet: showAiBottomSheet,
showEpisodes: showEpisodes,
onShowMemberPage: onShowMemberPage,
isPortrait: isPortrait,
isHorizontal: isHorizontal ?? width! / height! >= kScreenRatio,
),
if (needRelated && videoDetailController.showRelatedVideo) ...[
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.only(top: StyleString.safeSpace),
child: Divider(
height: 1,
indent: 12,
endIndent: 12,
color: themeData.colorScheme.outline.withValues(
alpha: 0.08,
),
Widget introPanel() {
Widget child = CustomScrollView(
key: const PageStorageKey(CommonIntroController),
controller: needCtr
? videoDetailController.effectiveIntroScrollCtr
: null,
physics: !needCtr
? const AlwaysScrollableScrollPhysics(
parent: ClampingScrollPhysics(),
)
: null,
slivers: [
if (videoDetailController.isUgc) ...[
UgcIntroPanel(
key: videoIntroKey,
heroTag: heroTag,
showAiBottomSheet: showAiBottomSheet,
showEpisodes: showEpisodes,
onShowMemberPage: onShowMemberPage,
isPortrait: isPortrait,
isHorizontal: isHorizontal ?? width! / height! >= kScreenRatio,
),
if (needRelated && videoDetailController.showRelatedVideo) ...[
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.only(
top: StyleString.safeSpace,
),
child: Divider(
height: 1,
indent: 12,
endIndent: 12,
color: themeData.colorScheme.outline.withValues(
alpha: 0.08,
),
),
),
RelatedVideoPanel(key: videoRelatedKey, heroTag: heroTag),
],
] else
PgcIntroPage(
key: videoIntroKey,
heroTag: heroTag,
cid: videoDetailController.cid.value,
showEpisodes: showEpisodes,
showIntroDetail: showIntroDetail,
maxWidth: width ?? maxWidth,
isLandscape: !isPortrait,
),
SliverToBoxAdapter(
child: SizedBox(
height:
(videoDetailController.isPlayAll && !isPortrait
? 80
: StyleString.safeSpace) +
padding.bottom,
),
RelatedVideoPanel(key: videoRelatedKey, heroTag: heroTag),
],
] else
PgcIntroPage(
key: videoIntroKey,
heroTag: heroTag,
cid: videoDetailController.cid.value,
showEpisodes: showEpisodes,
showIntroDetail: showIntroDetail,
maxWidth: width ?? maxWidth,
isLandscape: !isPortrait,
),
],
SliverToBoxAdapter(
child: SizedBox(
height:
(videoDetailController.isPlayAll && !isPortrait
? 80
: StyleString.safeSpace) +
padding.bottom,
),
),
],
);
if (isNested) {
child = ExtendedVisibilityDetector(
uniqueKey: const Key('intro-panel'),
child: child,
);
if (isNested) {
return ExtendedVisibilityDetector(
uniqueKey: const Key('intro-panel'),
child: child,
);
}
return child;
},
);
}
return KeepAliveWrapper(child: child);
}
if (videoDetailController.isPlayAll) {
return Stack(
clipBehavior: Clip.none,
@@ -1894,7 +1883,7 @@ class _VideoDetailPageVState extends State<VideoDetailPageV>
Widget get seasonPanel {
final videoDetail = ugcIntroController.videoDetail.value;
return KeepAliveWrapper(
builder: (context) => Column(
child: Column(
children: [
if ((videoDetail.pages?.length ?? 0) > 1)
if (videoDetail.ugcSeason != null)