diff --git a/lib/common/widgets/dynamic_sliver_appbar_medium.dart b/lib/common/widgets/dynamic_sliver_appbar_medium.dart index 2e4b03b8..010e9513 100644 --- a/lib/common/widgets/dynamic_sliver_appbar_medium.dart +++ b/lib/common/widgets/dynamic_sliver_appbar_medium.dart @@ -43,8 +43,10 @@ class DynamicSliverAppBarMedium extends StatefulWidget { this.forceMaterialTransparency = false, this.clipBehavior, this.appBarClipper, + this.callback, }); + final ValueChanged? callback; final Widget? flexibleSpace; final Widget? leading; final bool automaticallyImplyLeading; @@ -112,6 +114,7 @@ class _DynamicSliverAppBarMediumState extends State { _height = (_childKey.currentContext!.findRenderObject()! as RenderBox) .size .height; + widget.callback?.call(_height); }); }); } diff --git a/lib/models/space/filter.dart b/lib/models/space/filter.dart index 3d6b1751..f93c59a2 100644 --- a/lib/models/space/filter.dart +++ b/lib/models/space/filter.dart @@ -1,19 +1,19 @@ class SpaceTabFilter { - SpaceTabFilter({ + const SpaceTabFilter({ this.text, required this.meta, this.tabName, }); - String? text; - late String meta; - String? tabName; + final String? text; + final String meta; + final String? tabName; - SpaceTabFilter.fromJson(Map json) { - text = json['text']; - meta = json['meta'] ?? 'all'; - tabName = json['tab_ame']; - } + factory SpaceTabFilter.fromJson(Map json) => SpaceTabFilter( + text: json['text'], + meta: json['meta'] ?? 'all', + tabName: json['tab_ame'], + ); @override bool operator ==(Object other) { diff --git a/lib/pages/dynamics_topic/controller.dart b/lib/pages/dynamics_topic/controller.dart index d5ffe2d6..964d703c 100644 --- a/lib/pages/dynamics_topic/controller.dart +++ b/lib/pages/dynamics_topic/controller.dart @@ -20,6 +20,8 @@ class DynTopicController String offset = ''; Rx topicSortByConf = Rx(null); + double? appbarOffset; + // top final isLogin = Accounts.main.isLogin; Rx isFav = Rx(null); @@ -63,7 +65,14 @@ class DynTopicController @override Future onReload() { - scrollController.jumpToTop(); + if (appbarOffset != null) { + if (scrollController.hasClients && + scrollController.offset > appbarOffset!) { + scrollController.jumpTo(appbarOffset!); + } + } else { + scrollController.jumpToTop(); + } return super.onReload(); } diff --git a/lib/pages/dynamics_topic/view.dart b/lib/pages/dynamics_topic/view.dart index b77ba5b9..7d95859b 100644 --- a/lib/pages/dynamics_topic/view.dart +++ b/lib/pages/dynamics_topic/view.dart @@ -123,11 +123,14 @@ class _DynTopicPageState extends State { } Widget _buildAppBar(ThemeData theme, LoadingState topState) { + late final paddingTop = MediaQuery.paddingOf(context).top; return switch (topState) { Loading() => const SliverAppBar(), Success(:var response) when (topState.dataOrNull != null) => DynamicSliverAppBarMedium( pinned: true, + callback: (value) => _controller.appbarOffset = + value - kToolbarHeight - paddingTop - 7, title: IgnorePointer(child: Text(response!.topicItem!.name!)), flexibleSpace: Container( decoration: BoxDecoration( @@ -140,7 +143,7 @@ class _DynTopicPageState extends State { ), ), padding: EdgeInsets.only( - top: MediaQuery.paddingOf(context).top, + top: paddingTop, left: 12, right: 12, ), diff --git a/lib/pages/fav/view.dart b/lib/pages/fav/view.dart index 548664a1..2f11d0d8 100644 --- a/lib/pages/fav/view.dart +++ b/lib/pages/fav/view.dart @@ -5,6 +5,7 @@ import 'package:PiliPlus/models/user/fav_folder.dart'; import 'package:PiliPlus/pages/fav/video/controller.dart'; import 'package:PiliPlus/pages/fav_folder_sort/view.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; class FavPage extends StatefulWidget { @@ -77,6 +78,10 @@ class _FavPageState extends State with SingleTickerProviderStateMixin { () => _showVideoFavMenu.value ? IconButton( onPressed: () { + if (!_favController.isEnd) { + SmartDialog.showToast('加载全部收藏夹再排序'); + return; + } Get.to(FavFolderSortPage(favController: _favController)); }, icon: const Icon(Icons.sort), diff --git a/lib/pages/later/view.dart b/lib/pages/later/view.dart index 0b2217d2..d583e863 100644 --- a/lib/pages/later/view.dart +++ b/lib/pages/later/view.dart @@ -147,6 +147,7 @@ class _LaterPageState extends State ), Material( clipBehavior: Clip.hardEdge, + color: Colors.transparent, borderRadius: const BorderRadius.all(Radius.circular(20)), child: Builder( key: sortKey, @@ -197,6 +198,7 @@ class _LaterPageState extends State ), Material( clipBehavior: Clip.hardEdge, + color: Colors.transparent, borderRadius: const BorderRadius.all(Radius.circular(20)), child: PopupMenuButton( tooltip: '清空', diff --git a/lib/pages/member/controller.dart b/lib/pages/member/controller.dart index 2e6992f1..2923bff6 100644 --- a/lib/pages/member/controller.dart +++ b/lib/pages/member/controller.dart @@ -11,6 +11,8 @@ import 'package:PiliPlus/pages/common/common_data_controller.dart'; import 'package:PiliPlus/utils/request_utils.dart'; import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/utils.dart'; +import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart' + show ExtendedNestedScrollViewState; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; @@ -48,6 +50,9 @@ class MemberController extends CommonDataController final fromViewAid = Get.parameters['from_view_aid']; + final key = GlobalKey(); + int offset = 120; + @override void onInit() { super.onInit(); diff --git a/lib/pages/member/view.dart b/lib/pages/member/view.dart index 04898c84..61d108b2 100644 --- a/lib/pages/member/view.dart +++ b/lib/pages/member/view.dart @@ -28,8 +28,6 @@ class _MemberPageState extends State { late final int _mid; late final String _heroTag; late final MemberController _userController; - final _key = GlobalKey(); - int _offset = 120; @override void initState() { @@ -46,7 +44,7 @@ class _MemberPageState extends State { void listener() { if (_userController.scrollController.hasClients) { _userController.showUname.value = - _userController.scrollController.offset >= _offset; + _userController.scrollController.offset >= _userController.offset; } } @@ -169,7 +167,7 @@ class _MemberPageState extends State { ? LayoutBuilder( builder: (context, constraints) { return ExtendedNestedScrollView( - key: _key, + key: _userController.key, controller: _userController.scrollController, onlyOneScrollInBody: true, pinnedHeaderSliverHeightBuilder: () { @@ -213,7 +211,7 @@ class _MemberPageState extends State { tabs: _userController.tabs, onTap: (value) { if (_userController.tabController?.indexIsChanging == false) { - _key.currentState?.outerController.animToTop(); + _userController.key.currentState?.outerController.animToTop(); } }, ), @@ -253,7 +251,8 @@ class _MemberPageState extends State { toolbarHeight: kToolbarHeight + MediaQuery.paddingOf(context).top, flexibleSpace: _buildUserInfo(_userController.loadingState.value, isV), callback: (value) { - _offset = (value - 56 - MediaQuery.paddingOf(context).top).toInt(); + _userController.offset = + (value - 56 - MediaQuery.paddingOf(context).top).toInt(); listener(); }, ); diff --git a/lib/pages/member_opus/controller.dart b/lib/pages/member_opus/controller.dart index 77b52987..8d23b086 100644 --- a/lib/pages/member_opus/controller.dart +++ b/lib/pages/member_opus/controller.dart @@ -19,7 +19,7 @@ class MemberOpusController String offset = ''; Rx type = - SpaceTabFilter(text: "全部图文", meta: "all", tabName: "图文").obs; + const SpaceTabFilter(text: "全部图文", meta: "all", tabName: "图文").obs; List? filter; @override diff --git a/lib/pages/member_video/controller.dart b/lib/pages/member_video/controller.dart index bf508311..5e15d0a4 100644 --- a/lib/pages/member_video/controller.dart +++ b/lib/pages/member_video/controller.dart @@ -6,6 +6,7 @@ import 'package:PiliPlus/models/space_archive/data.dart'; import 'package:PiliPlus/models/space_archive/episodic_button.dart'; import 'package:PiliPlus/models/space_archive/item.dart'; import 'package:PiliPlus/pages/common/common_list_controller.dart'; +import 'package:PiliPlus/pages/member/controller.dart'; import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/id_utils.dart'; import 'package:PiliPlus/utils/page_utils.dart'; @@ -22,6 +23,7 @@ class MemberVideoCtr required this.seriesId, this.username, this.title, + this.heroTag, }); ContributeType type; @@ -43,6 +45,9 @@ class MemberVideoCtr bool? isLoadPrevious; bool? hasPrev; + String? heroTag; + late final MemberController _ctr = Get.find(tag: heroTag); + @override Future onRefresh() async { if (isLocating.value == true) { @@ -222,6 +227,11 @@ class MemberVideoCtr @override Future onReload() { isLocating.value = null; + if (_ctr.key.currentState?.outerController.hasClients == true) { + if (_ctr.key.currentState!.outerController.offset > _ctr.offset) { + _ctr.key.currentState!.outerController.jumpTo(_ctr.offset.toDouble()); + } + } return super.onReload(); } } diff --git a/lib/pages/member_video/view.dart b/lib/pages/member_video/view.dart index b819d2b8..f86fab08 100644 --- a/lib/pages/member_video/view.dart +++ b/lib/pages/member_video/view.dart @@ -49,6 +49,7 @@ class _MemberVideoState extends State seriesId: widget.seriesId, username: Get.find(tag: widget.heroTag).username, title: widget.title, + heroTag: widget.heroTag, ), tag: '${widget.heroTag}${widget.type.name}${widget.seasonId}${widget.seriesId}',