From 1943b65788520469c1a255b697d5425331e7c14e Mon Sep 17 00:00:00 2001 From: My-Responsitories <107370289+My-Responsitories@users.noreply.github.com> Date: Thu, 14 Aug 2025 23:50:45 +0800 Subject: [PATCH] opt: initialScrollIndex (#1018) --- lib/pages/episode_panel/view.dart | 40 ++++----------------- lib/pages/video/medialist/view.dart | 31 ++++------------ lib/pages/video/reply_reply/controller.dart | 31 ++++++++-------- lib/pages/video/reply_reply/view.dart | 7 ++-- 4 files changed, 33 insertions(+), 76 deletions(-) diff --git a/lib/pages/episode_panel/view.dart b/lib/pages/episode_panel/view.dart index 28774563..729a05e0 100644 --- a/lib/pages/episode_panel/view.dart +++ b/lib/pages/episode_panel/view.dart @@ -20,7 +20,7 @@ import 'package:PiliPlus/models_new/pgc/pgc_info_model/episode.dart' as pgc; import 'package:PiliPlus/models_new/video/video_detail/episode.dart' as ugc; import 'package:PiliPlus/models_new/video/video_detail/page.dart'; import 'package:PiliPlus/models_new/video/video_relation/data.dart'; -import 'package:PiliPlus/pages/common/slide/common_slide_page.dart'; +import 'package:PiliPlus/pages/common/slide/common_collapse_slide_page.dart'; import 'package:PiliPlus/pages/video/controller.dart'; import 'package:PiliPlus/pages/video/introduction/ugc/controller.dart'; import 'package:PiliPlus/pages/video/introduction/ugc/widgets/page.dart'; @@ -36,7 +36,7 @@ import 'package:get/get.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart'; -class EpisodePanel extends CommonSlidePage { +class EpisodePanel extends CommonCollapseSlidePage { const EpisodePanel({ super.key, super.enableSlide, @@ -83,7 +83,7 @@ class EpisodePanel extends CommonSlidePage { State createState() => _EpisodePanelState(); } -class _EpisodePanelState extends CommonSlidePageState { +class _EpisodePanelState extends CommonCollapseSlidePageState { // tab late final TabController _tabController = TabController( initialIndex: widget.initialTabIndex, @@ -109,8 +109,6 @@ class _EpisodePanelState extends CommonSlidePageState { // fav Rx? _favState; - late bool _isInit = true; - void listener() { _currentTabIndex.value = _tabController.index; } @@ -123,8 +121,8 @@ class _EpisodePanelState extends CommonSlidePageState { } void jumpToCurrent() { - int newItemIndex = _findCurrentItemIndex; - if (_currentItemIndex != _findCurrentItemIndex) { + final newItemIndex = _findCurrentItemIndex; + if (_currentItemIndex != newItemIndex) { _currentItemIndex = newItemIndex; try { _itemScrollController[_currentTabIndex.value].jumpTo( @@ -153,7 +151,7 @@ class _EpisodePanelState extends CommonSlidePageState { widget.list.length, (_) => ItemScrollController(), ); - _isReversed = List.generate(widget.list.length, (_) => false); + _isReversed = List.filled(widget.list.length, false); if (widget.type == EpisodeType.season && Accounts.main.isLogin) { _favState = LoadingState.loading().obs; @@ -168,20 +166,6 @@ class _EpisodePanelState extends CommonSlidePageState { } _currentItemIndex = _findCurrentItemIndex; - WidgetsBinding.instance.addPostFrameCallback((_) { - if (mounted) { - setState(() { - _isInit = false; - }); - WidgetsBinding.instance.addPostFrameCallback((_) { - try { - _itemScrollController[widget.initialTabIndex].jumpTo( - index: _currentItemIndex, - ); - } catch (_) {} - }); - } - }); } @override @@ -192,17 +176,6 @@ class _EpisodePanelState extends CommonSlidePageState { super.dispose(); } - @override - Widget build(BuildContext context) { - if (_isInit) { - return const CustomScrollView( - physics: NeverScrollableScrollPhysics(), - ); - } - - return super.build(context); - } - @override Widget buildPage(ThemeData theme) { final isMulti = widget.type == EpisodeType.season && widget.list.length > 1; @@ -281,6 +254,7 @@ class _EpisodePanelState extends CommonSlidePageState { ), reverse: _isReversed[tabIndex], itemCount: episodes.length, + initialScrollIndex: _currentItemIndex, physics: const AlwaysScrollableScrollPhysics(), itemBuilder: (BuildContext context, int itemIndex) { final episode = episodes[itemIndex]; diff --git a/lib/pages/video/medialist/view.dart b/lib/pages/video/medialist/view.dart index e62be873..d44935c9 100644 --- a/lib/pages/video/medialist/view.dart +++ b/lib/pages/video/medialist/view.dart @@ -50,34 +50,15 @@ class MediaListPanel extends CommonCollapseSlidePage { class _MediaListPanelState extends CommonCollapseSlidePageState { - final _scrollController = ItemScrollController(); - late RxBool desc; + late final int _index; + late final RxBool desc = widget.desc.obs; @override void initState() { super.initState(); - desc = widget.desc.obs; - } - - @override - void init() { - WidgetsBinding.instance.addPostFrameCallback((_) { - if (mounted) { - int index = widget.mediaList.indexWhere( - (item) => item.bvid == widget.getBvId(), - ); - if (index > 0) { - WidgetsBinding.instance.addPostFrameCallback((_) { - try { - _scrollController.jumpTo(index: index); - } catch (_) {} - }); - } - setState(() { - isInit = false; - }); - } - }); + final bvid = widget.getBvId(); + final bvIndex = widget.mediaList.indexWhere((item) => item.bvid == bvid); + _index = bvIndex == -1 ? 0 : bvIndex; } @override @@ -142,9 +123,9 @@ class _MediaListPanelState () { final showDelBtn = widget.onDelete != null && widget.mediaList.length > 1; return ScrollablePositionedList.separated( - itemScrollController: _scrollController, physics: const AlwaysScrollableScrollPhysics(), itemCount: widget.mediaList.length, + initialScrollIndex: _index, padding: EdgeInsets.only( top: 7, bottom: MediaQuery.paddingOf(context).bottom + 80, diff --git a/lib/pages/video/reply_reply/controller.dart b/lib/pages/video/reply_reply/controller.dart index d878135a..fd176340 100644 --- a/lib/pages/video/reply_reply/controller.dart +++ b/lib/pages/video/reply_reply/controller.dart @@ -7,6 +7,7 @@ import 'package:PiliPlus/pages/video/reply_new/view.dart'; import 'package:PiliPlus/utils/id_utils.dart'; import 'package:PiliPlus/utils/request_utils.dart'; import 'package:PiliPlus/utils/storage_pref.dart'; +import 'package:fixnum/fixnum.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:get/get_navigation/src/dialog/dialog_route.dart'; @@ -72,26 +73,26 @@ class VideoReplyReplyController extends ReplyController firstFloor = data.root; } if (id != null) { - index = data.root.replies.indexWhere((item) => item.id.toInt() == id); - if (index == -1) { - index = null; - } else { + final id64 = Int64(id!); + final index = data.root.replies.indexWhere((item) => item.id == id64); + if (index != -1) { + this.index = index; controller = AnimationController( duration: const Duration(milliseconds: 300), vsync: this, ); WidgetsBinding.instance.addPostFrameCallback((_) async { - if (index != null) { - try { - itemScrollCtr.jumpTo( - index: hasRoot ? index! + 3 : index! + 1, - alignment: 0.25, - ); - await Future.delayed(const Duration(milliseconds: 800)); - await controller?.forward(); - index = null; - } catch (_) {} - } + try { + itemScrollCtr.jumpTo( + index: hasRoot ? index + 3 : index + 1, + alignment: 0.25, + ); + await Future.delayed( + const Duration(milliseconds: 800), + controller?.forward, + ); + this.index = null; + } catch (_) {} }); } id = null; diff --git a/lib/pages/video/reply_reply/view.dart b/lib/pages/video/reply_reply/view.dart index 73b3bc7d..27d90c7e 100644 --- a/lib/pages/video/reply_reply/view.dart +++ b/lib/pages/video/reply_reply/view.dart @@ -321,6 +321,7 @@ class _VideoReplyReplyPanelState ), ); } else { + final child = _replyItem(response[index], index); if (_controller.index != null && _controller.index == index) { colorAnimation ??= ColorTween( begin: theme.colorScheme.onInverseSurface, @@ -328,17 +329,17 @@ class _VideoReplyReplyPanelState ).animate(_controller.controller!); return AnimatedBuilder( animation: colorAnimation!, - builder: (context, child) { + builder: (context, _) { return ColoredBox( color: colorAnimation!.value ?? theme.colorScheme.onInverseSurface, - child: _replyItem(response[index], index), + child: child, ); }, ); } - return _replyItem(response[index], index); + return child; } }, ),