diff --git a/lib/pages/article_list/view.dart b/lib/pages/article_list/view.dart index b2370315..db21282e 100644 --- a/lib/pages/article_list/view.dart +++ b/lib/pages/article_list/view.dart @@ -37,6 +37,7 @@ class _ArticleListPageState extends State { child: refreshIndicator( onRefresh: _controller.onRefresh, child: CustomScrollView( + physics: const AlwaysScrollableScrollPhysics(), slivers: [ Obx(() => _buildHeader(theme, _controller.list.value)), SliverPadding( diff --git a/lib/pages/bangumi/view.dart b/lib/pages/bangumi/view.dart index bbc2247c..20debfa6 100644 --- a/lib/pages/bangumi/view.dart +++ b/lib/pages/bangumi/view.dart @@ -14,6 +14,7 @@ import 'package:PiliPlus/pages/bangumi/controller.dart'; import 'package:PiliPlus/pages/bangumi/widgets/bangumi_card_v.dart'; import 'package:PiliPlus/pages/bangumi/widgets/bangumi_card_v_timeline.dart'; import 'package:PiliPlus/pages/common/common_page.dart'; +import 'package:PiliPlus/pages/pgc_index/controller.dart'; import 'package:PiliPlus/pages/pgc_index/view.dart'; import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/grid.dart'; @@ -241,25 +242,38 @@ class _BangumiPageState extends CommonPageState appBar: AppBar(title: const Text('索引')), body: DefaultTabController( length: types.length, - child: Column( - children: [ - SafeArea( - top: false, - bottom: false, - child: TabBar( + child: Builder(builder: (context) { + return Column( + children: [ + SafeArea( + top: false, + bottom: false, + child: TabBar( tabs: titles .map((title) => Tab(text: title)) - .toList()), - ), - Expanded( - child: tabBarView( - children: types - .map((type) => - PgcIndexPage(indexType: type)) - .toList()), - ) - ], - ), + .toList(), + onTap: (index) { + try { + if (!DefaultTabController.of(context) + .indexIsChanging) { + Get.find( + tag: types[index].toString()) + .animateToTop(); + } + } catch (_) {} + }, + ), + ), + Expanded( + child: tabBarView( + children: types + .map((type) => + PgcIndexPage(indexType: type)) + .toList()), + ) + ], + ); + }), ), ), ); diff --git a/lib/pages/dynamics_topic/view.dart b/lib/pages/dynamics_topic/view.dart index a5c273ee..deeeab71 100644 --- a/lib/pages/dynamics_topic/view.dart +++ b/lib/pages/dynamics_topic/view.dart @@ -46,6 +46,7 @@ class _DynTopicPageState extends State { onRefresh: _controller.onRefresh, child: CustomScrollView( controller: _controller.scrollController, + physics: const AlwaysScrollableScrollPhysics(), slivers: [ Obx(() => _buildAppBar(theme, _controller.topState.value)), Obx(() { diff --git a/lib/pages/fav/article/view.dart b/lib/pages/fav/article/view.dart index b0de1363..abe3b75f 100644 --- a/lib/pages/fav/article/view.dart +++ b/lib/pages/fav/article/view.dart @@ -31,6 +31,8 @@ class _FavArticlePageState extends State return refreshIndicator( onRefresh: _favArticleController.onRefresh, child: CustomScrollView( + controller: _favArticleController.scrollController, + physics: const AlwaysScrollableScrollPhysics(), slivers: [ SliverPadding( padding: EdgeInsets.only( diff --git a/lib/pages/fav/note/child_view.dart b/lib/pages/fav/note/child_view.dart index 312f791d..2c644e8a 100644 --- a/lib/pages/fav/note/child_view.dart +++ b/lib/pages/fav/note/child_view.dart @@ -36,6 +36,8 @@ class _FavNoteChildPageState extends State refreshIndicator( onRefresh: _favNoteController.onRefresh, child: CustomScrollView( + controller: _favNoteController.scrollController, + physics: const AlwaysScrollableScrollPhysics(), slivers: [ SliverPadding( padding: EdgeInsets.only( diff --git a/lib/pages/fav/note/view.dart b/lib/pages/fav/note/view.dart index b053e4b5..ac16a0a7 100644 --- a/lib/pages/fav/note/view.dart +++ b/lib/pages/fav/note/view.dart @@ -1,5 +1,8 @@ import 'package:PiliPlus/pages/fav/note/child_view.dart'; +import 'package:PiliPlus/pages/fav/note/controller.dart'; +import 'package:PiliPlus/utils/extension.dart'; import 'package:flutter/material.dart'; +import 'package:get/get.dart'; class FavNotePage extends StatefulWidget { const FavNotePage({super.key}); @@ -58,6 +61,16 @@ class _FavNotePageState extends State const Tab(text: '未发布笔记'), const Tab(text: '公开笔记'), ], + onTap: (index) { + try { + if (!_tabController.indexIsChanging) { + Get.find( + tag: index == 0 ? 'false' : 'true') + .scrollController + .animToTop(); + } + } catch (_) {} + }, ), ), // TextButton( diff --git a/lib/pages/fav/pgc/child_view.dart b/lib/pages/fav/pgc/child_view.dart index 1dbe9824..9b108546 100644 --- a/lib/pages/fav/pgc/child_view.dart +++ b/lib/pages/fav/pgc/child_view.dart @@ -43,6 +43,8 @@ class _FavPgcChildPageState extends State refreshIndicator( onRefresh: _favPgcController.onRefresh, child: CustomScrollView( + controller: _favPgcController.scrollController, + physics: const AlwaysScrollableScrollPhysics(), slivers: [ SliverPadding( padding: EdgeInsets.only( diff --git a/lib/pages/fav/pgc/view.dart b/lib/pages/fav/pgc/view.dart index 5b12e9fc..cee4d552 100644 --- a/lib/pages/fav/pgc/view.dart +++ b/lib/pages/fav/pgc/view.dart @@ -1,5 +1,8 @@ import 'package:PiliPlus/pages/fav/pgc/child_view.dart'; +import 'package:PiliPlus/pages/fav/pgc/controller.dart'; +import 'package:PiliPlus/utils/extension.dart'; import 'package:flutter/material.dart'; +import 'package:get/get.dart'; class FavPgcPage extends StatefulWidget { const FavPgcPage({super.key, required this.type}); @@ -61,6 +64,15 @@ class _FavPgcPageState extends State Tab(text: '在看'), Tab(text: '看过'), ], + onTap: (index) { + try { + if (!_tabController.indexIsChanging) { + Get.find( + tag: '${widget.type}${index + 1}', + ).scrollController.animToTop(); + } + } catch (_) {} + }, ), ), // TextButton( diff --git a/lib/pages/fav/topic/view.dart b/lib/pages/fav/topic/view.dart index d6c59cac..855fa15c 100644 --- a/lib/pages/fav/topic/view.dart +++ b/lib/pages/fav/topic/view.dart @@ -30,6 +30,8 @@ class _FavTopicPageState extends State return refreshIndicator( onRefresh: _controller.onRefresh, child: CustomScrollView( + controller: _controller.scrollController, + physics: const AlwaysScrollableScrollPhysics(), slivers: [ SliverPadding( padding: EdgeInsets.only( diff --git a/lib/pages/fav/view.dart b/lib/pages/fav/view.dart index 8693dece..5bc619b3 100644 --- a/lib/pages/fav/view.dart +++ b/lib/pages/fav/view.dart @@ -2,8 +2,11 @@ import 'package:PiliPlus/common/widgets/scroll_physics.dart'; import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/models/common/fav_type.dart'; import 'package:PiliPlus/models/user/fav_folder.dart'; +import 'package:PiliPlus/pages/fav/article/controller.dart'; +import 'package:PiliPlus/pages/fav/topic/controller.dart'; import 'package:PiliPlus/pages/fav/video/controller.dart'; import 'package:PiliPlus/pages/fav_folder_sort/view.dart'; +import 'package:PiliPlus/utils/extension.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; @@ -122,6 +125,23 @@ class _FavPageState extends State with SingleTickerProviderStateMixin { isScrollable: true, tabAlignment: TabAlignment.start, tabs: FavTabType.values.map((item) => Tab(text: item.title)).toList(), + onTap: (index) { + try { + if (!_tabController.indexIsChanging) { + switch (FavTabType.values[index]) { + case FavTabType.video: + _favController.scrollController.animToTop(); + case FavTabType.article: + Get.find() + .scrollController + .animToTop(); + case FavTabType.topic: + Get.find().scrollController.animToTop(); + default: + } + } + } catch (_) {} + }, ), ), body: SafeArea( diff --git a/lib/pages/live_area_detail/child/view.dart b/lib/pages/live_area_detail/child/view.dart index e35b044f..29814fec 100644 --- a/lib/pages/live_area_detail/child/view.dart +++ b/lib/pages/live_area_detail/child/view.dart @@ -40,6 +40,8 @@ class _LiveAreaChildPageState extends State return refreshIndicator( onRefresh: _controller.onRefresh, child: CustomScrollView( + controller: _controller.scrollController, + physics: const AlwaysScrollableScrollPhysics(), slivers: [ SliverPadding( padding: EdgeInsets.only( diff --git a/lib/pages/live_area_detail/view.dart b/lib/pages/live_area_detail/view.dart index 2c1a2b3d..46e80696 100644 --- a/lib/pages/live_area_detail/view.dart +++ b/lib/pages/live_area_detail/view.dart @@ -4,6 +4,7 @@ import 'package:PiliPlus/common/widgets/scroll_physics.dart'; import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/models/common/image_type.dart'; import 'package:PiliPlus/models/live/live_area_list/area_item.dart'; +import 'package:PiliPlus/pages/live_area_detail/child/controller.dart'; import 'package:PiliPlus/pages/live_area_detail/child/view.dart'; import 'package:PiliPlus/pages/live_area_detail/controller.dart'; import 'package:PiliPlus/pages/live_search/view.dart'; @@ -76,6 +77,17 @@ class _LiveAreaDetailPageState extends State { tabs: response .map((e) => Tab(text: e.name ?? '')) .toList(), + onTap: (index) { + try { + if (!DefaultTabController.of(context) + .indexIsChanging) { + final item = response[index]; + Get.find( + tag: '${item.id}${item.parentId}') + .animateToTop(); + } + } catch (_) {} + }, ), ), iconButton( diff --git a/lib/pages/live_follow/view.dart b/lib/pages/live_follow/view.dart index 5a51b27e..08b807d3 100644 --- a/lib/pages/live_follow/view.dart +++ b/lib/pages/live_follow/view.dart @@ -36,6 +36,7 @@ class _LiveFollowPageState extends State { child: refreshIndicator( onRefresh: _controller.onRefresh, child: CustomScrollView( + physics: const AlwaysScrollableScrollPhysics(), slivers: [ SliverPadding( padding: EdgeInsets.only( diff --git a/lib/pages/live_search/view.dart b/lib/pages/live_search/view.dart index 95e251bc..06e2d834 100644 --- a/lib/pages/live_search/view.dart +++ b/lib/pages/live_search/view.dart @@ -77,20 +77,32 @@ class _LiveSearchPageState extends State { ), ), ], + onTap: (index) { + if (!_controller.tabController.indexIsChanging) { + if (index == 0) { + _controller.roomCtr.animateToTop(); + } else { + _controller.userCtr.animateToTop(); + } + } + }, ), Expanded( - child: tabBarView( - controller: _controller.tabController, - children: [ - LiveSearchChildPage( - controller: _controller.roomCtr, - searchType: LiveSearchType.room, - ), - LiveSearchChildPage( - controller: _controller.userCtr, - searchType: LiveSearchType.user, - ), - ], + child: Material( + color: Colors.transparent, + child: tabBarView( + controller: _controller.tabController, + children: [ + LiveSearchChildPage( + controller: _controller.roomCtr, + searchType: LiveSearchType.room, + ), + LiveSearchChildPage( + controller: _controller.userCtr, + searchType: LiveSearchType.user, + ), + ], + ), ), ), ], diff --git a/lib/pages/main/nav.dart b/lib/pages/main/nav.dart index 571e95c5..8467e08e 100644 --- a/lib/pages/main/nav.dart +++ b/lib/pages/main/nav.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// ignore_for_file: uri_does_not_exist_in_doc_import + /// @docImport 'package:flutter/services.dart'; /// @docImport 'bottom_navigation_bar.dart'; /// @docImport 'navigation_rail.dart'; diff --git a/lib/pages/member_article/view.dart b/lib/pages/member_article/view.dart index e0b368cd..fba00ee2 100644 --- a/lib/pages/member_article/view.dart +++ b/lib/pages/member_article/view.dart @@ -39,6 +39,7 @@ class _MemberArticleState extends State return refreshIndicator( onRefresh: _controller.onRefresh, child: CustomScrollView( + physics: const AlwaysScrollableScrollPhysics(), slivers: [ SliverPadding( padding: EdgeInsets.only( diff --git a/lib/pages/member_favorite/view.dart b/lib/pages/member_favorite/view.dart index 2866bff8..0aaacc9f 100644 --- a/lib/pages/member_favorite/view.dart +++ b/lib/pages/member_favorite/view.dart @@ -41,6 +41,7 @@ class _MemberFavoriteState extends State return refreshIndicator( onRefresh: _controller.onRefresh, child: CustomScrollView( + physics: const AlwaysScrollableScrollPhysics(), slivers: [ SliverPadding( padding: EdgeInsets.only( diff --git a/lib/pages/member_opus/view.dart b/lib/pages/member_opus/view.dart index 1f78ce98..1ebdd9be 100644 --- a/lib/pages/member_opus/view.dart +++ b/lib/pages/member_opus/view.dart @@ -45,6 +45,7 @@ class _MemberOpusState extends State refreshIndicator( onRefresh: _controller.onRefresh, child: CustomScrollView( + physics: const AlwaysScrollableScrollPhysics(), slivers: [ SliverPadding( padding: EdgeInsets.only( diff --git a/lib/pages/member_pgc/view.dart b/lib/pages/member_pgc/view.dart index 29f2a7af..9c4ef4b8 100644 --- a/lib/pages/member_pgc/view.dart +++ b/lib/pages/member_pgc/view.dart @@ -42,6 +42,7 @@ class _MemberBangumiState extends State return refreshIndicator( onRefresh: _controller.onRefresh, child: CustomScrollView( + physics: const AlwaysScrollableScrollPhysics(), slivers: [ SliverPadding( padding: EdgeInsets.only( diff --git a/lib/pages/member_search/child/view.dart b/lib/pages/member_search/child/view.dart index 9f40fae3..27ae848f 100644 --- a/lib/pages/member_search/child/view.dart +++ b/lib/pages/member_search/child/view.dart @@ -41,6 +41,7 @@ class _MemberSearchChildPageState extends State onRefresh: _controller.onRefresh, child: CustomScrollView( controller: _controller.scrollController, + physics: const AlwaysScrollableScrollPhysics(), slivers: [ SliverPadding( padding: EdgeInsets.only( diff --git a/lib/pages/member_search/view.dart b/lib/pages/member_search/view.dart index 1f96c47a..92870722 100644 --- a/lib/pages/member_search/view.dart +++ b/lib/pages/member_search/view.dart @@ -80,6 +80,15 @@ class _MemberSearchPageState extends State { ), ), ], + onTap: (index) { + if (!_controller.tabController.indexIsChanging) { + if (index == 0) { + _controller.arcCtr.animateToTop(); + } else { + _controller.dynCtr.animateToTop(); + } + } + }, ), Expanded( child: tabBarView( diff --git a/lib/pages/pgc_index/controller.dart b/lib/pages/pgc_index/controller.dart index 13a2f5bf..82a835e5 100644 --- a/lib/pages/pgc_index/controller.dart +++ b/lib/pages/pgc_index/controller.dart @@ -7,7 +7,8 @@ import 'package:get/get.dart'; class PgcIndexController extends CommonListController { PgcIndexController(this.indexType); int? indexType; - Rx conditionState = LoadingState.loading().obs; + Rx> conditionState = + LoadingState.loading().obs; late final RxBool isExpand = false.obs; diff --git a/lib/pages/pgc_index/view.dart b/lib/pages/pgc_index/view.dart index b7e95427..f5e6d026 100644 --- a/lib/pages/pgc_index/view.dart +++ b/lib/pages/pgc_index/view.dart @@ -42,17 +42,18 @@ class _PgcIndexPageState extends State : Obx(() => _buildBody(theme, _ctr.conditionState.value)); } - Widget _buildBody(ThemeData theme, LoadingState loadingState) { + Widget _buildBody( + ThemeData theme, LoadingState loadingState) { return switch (loadingState) { Loading() => loadingWidget, Success(:var response) => Builder(builder: (context) { - PgcIndexCondition data = response; - int count = (data.order?.isNotEmpty == true ? 1 : 0) + - (data.filter?.length ?? 0); + int count = (response.order?.isNotEmpty == true ? 1 : 0) + + (response.filter?.length ?? 0); if (count == 0) return const SizedBox.shrink(); return SafeArea( bottom: false, child: CustomScrollView( + controller: _ctr.scrollController, slivers: [ if (widget.indexType != null) const SliverToBoxAdapter(child: SizedBox(height: 12)), @@ -62,8 +63,8 @@ class _PgcIndexPageState extends State alignment: Alignment.topCenter, duration: const Duration(milliseconds: 200), child: count > 5 - ? Obx(() => _buildSortWidget(theme, count, data)) - : _buildSortWidget(theme, count, data), + ? Obx(() => _buildSortWidget(theme, count, response)) + : _buildSortWidget(theme, count, response), ), ), SliverPadding( diff --git a/lib/pages/rank/zone/view.dart b/lib/pages/rank/zone/view.dart index fe3b0c9c..8fa3fb21 100644 --- a/lib/pages/rank/zone/view.dart +++ b/lib/pages/rank/zone/view.dart @@ -40,6 +40,7 @@ class _ZonePageState extends CommonPageState onRefresh: controller.onRefresh, child: CustomScrollView( controller: controller.scrollController, + physics: const AlwaysScrollableScrollPhysics(), slivers: [ SliverPadding( padding: EdgeInsets.only( diff --git a/lib/pages/search_trending/view.dart b/lib/pages/search_trending/view.dart index 4c2aacc3..261e96a0 100644 --- a/lib/pages/search_trending/view.dart +++ b/lib/pages/search_trending/view.dart @@ -114,6 +114,7 @@ class _SearchTrendingPageState extends State { onRefresh: _controller.onRefresh, child: CustomScrollView( controller: _controller.scrollController, + physics: const AlwaysScrollableScrollPhysics(), slivers: [ SliverToBoxAdapter( child: Image.asset( diff --git a/lib/pages/subscription/view.dart b/lib/pages/subscription/view.dart index c1e5b952..408a19d6 100644 --- a/lib/pages/subscription/view.dart +++ b/lib/pages/subscription/view.dart @@ -29,6 +29,7 @@ class _SubPageState extends State { child: refreshIndicator( onRefresh: _subController.onRefresh, child: CustomScrollView( + physics: const AlwaysScrollableScrollPhysics(), slivers: [ Obx(() => _buildBody(_subController.loadingState.value)), SliverToBoxAdapter( diff --git a/lib/pages/video/medialist/view.dart b/lib/pages/video/medialist/view.dart index 18fe6f43..e8a730ac 100644 --- a/lib/pages/video/medialist/view.dart +++ b/lib/pages/video/medialist/view.dart @@ -138,9 +138,6 @@ class _MediaListPanelState widget.onDelete != null && widget.mediaList.length > 1; return ScrollablePositionedList.separated( itemScrollController: _scrollController, - // physics: const PositionRetainedScrollPhysics( - // parent: ClampingScrollPhysics(), - // ), physics: const AlwaysScrollableScrollPhysics(), itemCount: widget.mediaList.length, padding: EdgeInsets.only( diff --git a/lib/pages/video/member/view.dart b/lib/pages/video/member/view.dart index b46ba26c..39adb6a2 100644 --- a/lib/pages/video/member/view.dart +++ b/lib/pages/video/member/view.dart @@ -92,10 +92,7 @@ class _HorizontalMemberPageState extends State { onRefresh: _controller.onRefresh, child: CustomScrollView( controller: _controller.scrollController, - // physics: PositionRetainedScrollPhysics( - // shouldRetain: _controller.hasPrev, - // parent: const ClampingScrollPhysics(), - // ), + physics: const AlwaysScrollableScrollPhysics(), slivers: [ _buildSliverHeader(theme), Obx(() =>