diff --git a/lib/pages/member/controller.dart b/lib/pages/member/controller.dart index 18d3c4b24..fd4653878 100644 --- a/lib/pages/member/controller.dart +++ b/lib/pages/member/controller.dart @@ -14,6 +14,7 @@ import 'package:PiliPlus/models_new/space/space/setting.dart'; import 'package:PiliPlus/models_new/space/space/tab2.dart'; import 'package:PiliPlus/pages/common/common_data_controller.dart'; import 'package:PiliPlus/utils/accounts.dart'; +import 'package:PiliPlus/utils/extension/nested_scroll_ext.dart'; import 'package:PiliPlus/utils/request_utils.dart'; import 'package:PiliPlus/utils/share_utils.dart'; import 'package:PiliPlus/utils/storage_pref.dart'; @@ -59,7 +60,7 @@ class MemberController extends CommonDataController final fromViewAid = Get.parameters['from_view_aid']; - final key = GlobalKey(); + final scrollKey = GlobalKey(); @override void onInit() { @@ -255,13 +256,8 @@ class MemberController extends CommonDataController } void onTapTab(int value) { - if (tabController?.indexIsChanging == false && - key.currentState?.outerController.hasClients == true) { - key.currentState!.outerController.animateTo( - key.currentState!.outerController.offset, - duration: const Duration(milliseconds: 500), - curve: Curves.easeInOut, - ); + if (tabController?.indexIsChanging == false) { + scrollKey.currentState?.animToTop(); } } diff --git a/lib/pages/member/view.dart b/lib/pages/member/view.dart index 8627fda5e..e0b52d4dc 100644 --- a/lib/pages/member/view.dart +++ b/lib/pages/member/view.dart @@ -92,7 +92,7 @@ class _MemberPageState extends State { () => switch (_userController.loadingState.value) { Loading() => m3eLoading, Success(:final response) => ExtendedNestedScrollView( - key: _userController.key, + key: _userController.scrollKey, onlyOneScrollInBody: true, pinnedHeaderSliverHeightBuilder: () => kToolbarHeight + MediaQuery.viewPaddingOf(context).top, diff --git a/lib/pages/member_video/view.dart b/lib/pages/member_video/view.dart index d9185d8e2..3f608f583 100644 --- a/lib/pages/member_video/view.dart +++ b/lib/pages/member_video/view.dart @@ -11,7 +11,6 @@ import 'package:PiliPlus/pages/member/controller.dart'; import 'package:PiliPlus/pages/member_video/controller.dart'; import 'package:PiliPlus/pages/member_video/widgets/video_card_h_member_video.dart'; import 'package:PiliPlus/utils/grid.dart'; -import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'; import 'package:flutter/foundation.dart' show kDebugMode; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; @@ -53,19 +52,18 @@ class _MemberVideoState extends State late final MemberVideoCtr _controller; - int? _index; - late ExtendedNestedScrollController _scrollController; - void _jumpToIndex(int index) { final scrollOffset = gridDelegate.layoutCache! .getGeometryForChildIndex(index) .scrollOffset; try { - _scrollController.nestedPositions - .elementAt(_index!) - .localJumpTo(scrollOffset); + final state = Get.find( + tag: widget.heroTag, + ).scrollKey.currentState; + if (state != null && state.mounted) { + state.innerNestedPositions.first.localJumpTo(scrollOffset); + } } catch (e) { - _scrollController.jumpTo(scrollOffset); if (kDebugMode) debugPrint('jump error: $e'); } } @@ -118,12 +116,6 @@ class _MemberVideoState extends State ), ); if (_controller.isVideo && _controller.fromViewAid?.isNotEmpty == true) { - if (_index == null) { - _scrollController = - PrimaryScrollController.of(this.context) - as ExtendedNestedScrollController; - _index = _scrollController.nestedPositions.length; - } return Stack( clipBehavior: Clip.none, children: [ diff --git a/lib/pages/video/controller.dart b/lib/pages/video/controller.dart index ba171bbd1..efaf5c92b 100644 --- a/lib/pages/video/controller.dart +++ b/lib/pages/video/controller.dart @@ -54,6 +54,7 @@ import 'package:PiliPlus/utils/accounts.dart'; import 'package:PiliPlus/utils/connectivity_utils.dart'; import 'package:PiliPlus/utils/extension/context_ext.dart'; import 'package:PiliPlus/utils/extension/iterable_ext.dart'; +import 'package:PiliPlus/utils/extension/nested_scroll_ext.dart'; import 'package:PiliPlus/utils/extension/num_ext.dart'; import 'package:PiliPlus/utils/extension/size_ext.dart'; import 'package:PiliPlus/utils/page_utils.dart'; @@ -187,9 +188,7 @@ class VideoDetailController extends GetxController )..addListener(_animListener)); void refreshPage() { - if (scrollKey.currentState?.mounted ?? false) { - (scrollKey.currentState!.context as Element).markNeedsBuild(); - } + scrollKey.currentState?.refresh(); } void _animListener() { @@ -217,14 +216,7 @@ class VideoDetailController extends GetxController } void animToTop() { - final outerController = scrollKey.currentState!.outerController; - if (outerController.hasClients) { - outerController.animateTo( - outerController.offset, - duration: const Duration(milliseconds: 500), - curve: Curves.easeInOut, - ); - } + scrollKey.currentState?.animToTop(); } bool _needAnimOnDimensionChanged(bool isVertical) { diff --git a/lib/pages/video/introduction/local/controller.dart b/lib/pages/video/introduction/local/controller.dart index f36a8110d..299469576 100644 --- a/lib/pages/video/introduction/local/controller.dart +++ b/lib/pages/video/introduction/local/controller.dart @@ -71,9 +71,9 @@ class LocalIntroController extends CommonIntroController { if (index != 0) { SchedulerBinding.instance.addPostFrameCallback((_) { try { - if (videoDetailCtr.scrollKey.currentState?.mounted ?? false) { - (videoDetailCtr.scrollKey.currentState!.innerController - as ExtendedNestedScrollController) + final state = videoDetailCtr.scrollKey.currentState; + if (state != null && state.mounted) { + (state.innerController as ExtendedNestedScrollController) .nestedPositions .first .localJumpTo(_offset); diff --git a/lib/utils/extension/nested_scroll_ext.dart b/lib/utils/extension/nested_scroll_ext.dart new file mode 100644 index 000000000..44e15fcde --- /dev/null +++ b/lib/utils/extension/nested_scroll_ext.dart @@ -0,0 +1,26 @@ +import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart' + show ExtendedNestedScrollViewState; +import 'package:flutter/widgets.dart' show Element, Curves; + +extension ExtendedNestedScrollViewStateExt on ExtendedNestedScrollViewState { + void refresh() { + if (mounted) { + (context as Element).markNeedsBuild(); + } + } + + void animToTop() { + if (mounted) { + final position = innerNestedPositions.first; + if (position.pixels >= position.viewportDimension * 7) { + position.localJumpTo(0); + } else { + outerController.animateTo( + outerController.offset, + curve: Curves.easeInOut, + duration: const Duration(milliseconds: 500), + ); + } + } + } +} diff --git a/pubspec.lock b/pubspec.lock index e53656aac..618079497 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -485,7 +485,7 @@ packages: description: path: "." ref: mod - resolved-ref: "4f39947d2ceda6fa56503e0efc794fcf0d4ef5a6" + resolved-ref: "161cd202c20bf0ba2394e3a86381d58864dc9e4e" url: "https://github.com/bggRGjQaUbCoE/extended_nested_scroll_view.git" source: git version: "6.2.1"