opt nested scroll

Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-06-28 20:25:39 +08:00
parent add6dfc389
commit ace9404f5a
7 changed files with 44 additions and 38 deletions

View File

@@ -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/models_new/space/space/tab2.dart';
import 'package:PiliPlus/pages/common/common_data_controller.dart'; import 'package:PiliPlus/pages/common/common_data_controller.dart';
import 'package:PiliPlus/utils/accounts.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/request_utils.dart';
import 'package:PiliPlus/utils/share_utils.dart'; import 'package:PiliPlus/utils/share_utils.dart';
import 'package:PiliPlus/utils/storage_pref.dart'; import 'package:PiliPlus/utils/storage_pref.dart';
@@ -59,7 +60,7 @@ class MemberController extends CommonDataController<SpaceData, SpaceData?>
final fromViewAid = Get.parameters['from_view_aid']; final fromViewAid = Get.parameters['from_view_aid'];
final key = GlobalKey<ExtendedNestedScrollViewState>(); final scrollKey = GlobalKey<ExtendedNestedScrollViewState>();
@override @override
void onInit() { void onInit() {
@@ -255,13 +256,8 @@ class MemberController extends CommonDataController<SpaceData, SpaceData?>
} }
void onTapTab(int value) { void onTapTab(int value) {
if (tabController?.indexIsChanging == false && if (tabController?.indexIsChanging == false) {
key.currentState?.outerController.hasClients == true) { scrollKey.currentState?.animToTop();
key.currentState!.outerController.animateTo(
key.currentState!.outerController.offset,
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOut,
);
} }
} }

View File

@@ -92,7 +92,7 @@ class _MemberPageState extends State<MemberPage> {
() => switch (_userController.loadingState.value) { () => switch (_userController.loadingState.value) {
Loading() => m3eLoading, Loading() => m3eLoading,
Success(:final response) => ExtendedNestedScrollView( Success(:final response) => ExtendedNestedScrollView(
key: _userController.key, key: _userController.scrollKey,
onlyOneScrollInBody: true, onlyOneScrollInBody: true,
pinnedHeaderSliverHeightBuilder: () => pinnedHeaderSliverHeightBuilder: () =>
kToolbarHeight + MediaQuery.viewPaddingOf(context).top, kToolbarHeight + MediaQuery.viewPaddingOf(context).top,

View File

@@ -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/controller.dart';
import 'package:PiliPlus/pages/member_video/widgets/video_card_h_member_video.dart'; import 'package:PiliPlus/pages/member_video/widgets/video_card_h_member_video.dart';
import 'package:PiliPlus/utils/grid.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/foundation.dart' show kDebugMode;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
@@ -53,19 +52,18 @@ class _MemberVideoState extends State<MemberVideo>
late final MemberVideoCtr _controller; late final MemberVideoCtr _controller;
int? _index;
late ExtendedNestedScrollController _scrollController;
void _jumpToIndex(int index) { void _jumpToIndex(int index) {
final scrollOffset = gridDelegate.layoutCache! final scrollOffset = gridDelegate.layoutCache!
.getGeometryForChildIndex(index) .getGeometryForChildIndex(index)
.scrollOffset; .scrollOffset;
try { try {
_scrollController.nestedPositions final state = Get.find<MemberController>(
.elementAt(_index!) tag: widget.heroTag,
.localJumpTo(scrollOffset); ).scrollKey.currentState;
if (state != null && state.mounted) {
state.innerNestedPositions.first.localJumpTo(scrollOffset);
}
} catch (e) { } catch (e) {
_scrollController.jumpTo(scrollOffset);
if (kDebugMode) debugPrint('jump error: $e'); if (kDebugMode) debugPrint('jump error: $e');
} }
} }
@@ -118,12 +116,6 @@ class _MemberVideoState extends State<MemberVideo>
), ),
); );
if (_controller.isVideo && _controller.fromViewAid?.isNotEmpty == true) { if (_controller.isVideo && _controller.fromViewAid?.isNotEmpty == true) {
if (_index == null) {
_scrollController =
PrimaryScrollController.of(this.context)
as ExtendedNestedScrollController;
_index = _scrollController.nestedPositions.length;
}
return Stack( return Stack(
clipBehavior: Clip.none, clipBehavior: Clip.none,
children: [ children: [

View File

@@ -54,6 +54,7 @@ import 'package:PiliPlus/utils/accounts.dart';
import 'package:PiliPlus/utils/connectivity_utils.dart'; import 'package:PiliPlus/utils/connectivity_utils.dart';
import 'package:PiliPlus/utils/extension/context_ext.dart'; import 'package:PiliPlus/utils/extension/context_ext.dart';
import 'package:PiliPlus/utils/extension/iterable_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/num_ext.dart';
import 'package:PiliPlus/utils/extension/size_ext.dart'; import 'package:PiliPlus/utils/extension/size_ext.dart';
import 'package:PiliPlus/utils/page_utils.dart'; import 'package:PiliPlus/utils/page_utils.dart';
@@ -187,9 +188,7 @@ class VideoDetailController extends GetxController
)..addListener(_animListener)); )..addListener(_animListener));
void refreshPage() { void refreshPage() {
if (scrollKey.currentState?.mounted ?? false) { scrollKey.currentState?.refresh();
(scrollKey.currentState!.context as Element).markNeedsBuild();
}
} }
void _animListener() { void _animListener() {
@@ -217,14 +216,7 @@ class VideoDetailController extends GetxController
} }
void animToTop() { void animToTop() {
final outerController = scrollKey.currentState!.outerController; scrollKey.currentState?.animToTop();
if (outerController.hasClients) {
outerController.animateTo(
outerController.offset,
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOut,
);
}
} }
bool _needAnimOnDimensionChanged(bool isVertical) { bool _needAnimOnDimensionChanged(bool isVertical) {

View File

@@ -71,9 +71,9 @@ class LocalIntroController extends CommonIntroController {
if (index != 0) { if (index != 0) {
SchedulerBinding.instance.addPostFrameCallback((_) { SchedulerBinding.instance.addPostFrameCallback((_) {
try { try {
if (videoDetailCtr.scrollKey.currentState?.mounted ?? false) { final state = videoDetailCtr.scrollKey.currentState;
(videoDetailCtr.scrollKey.currentState!.innerController if (state != null && state.mounted) {
as ExtendedNestedScrollController) (state.innerController as ExtendedNestedScrollController)
.nestedPositions .nestedPositions
.first .first
.localJumpTo(_offset); .localJumpTo(_offset);

View File

@@ -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),
);
}
}
}
}

View File

@@ -485,7 +485,7 @@ packages:
description: description:
path: "." path: "."
ref: mod ref: mod
resolved-ref: "4f39947d2ceda6fa56503e0efc794fcf0d4ef5a6" resolved-ref: "161cd202c20bf0ba2394e3a86381d58864dc9e4e"
url: "https://github.com/bggRGjQaUbCoE/extended_nested_scroll_view.git" url: "https://github.com/bggRGjQaUbCoE/extended_nested_scroll_view.git"
source: git source: git
version: "6.2.1" version: "6.2.1"