mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
@@ -318,4 +318,11 @@ class DynamicsController extends GetxController
|
||||
.animateToTop();
|
||||
scrollController.animToTop();
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
tabController.dispose();
|
||||
scrollController.dispose();
|
||||
super.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,9 +32,8 @@ class DynamicDetailPage extends StatefulWidget {
|
||||
class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
with TickerProviderStateMixin {
|
||||
late DynamicDetailController _dynamicDetailController;
|
||||
late AnimationController fabAnimationCtr;
|
||||
late StreamController<bool> titleStreamC; // appBar title
|
||||
late ScrollController scrollController;
|
||||
AnimationController? _fabAnimationCtr;
|
||||
late StreamController<bool> _titleStreamC; // appBar title
|
||||
bool _visibleTitle = false;
|
||||
String? action;
|
||||
// 回复类型
|
||||
@@ -49,17 +48,17 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
super.initState();
|
||||
// floor 1原创 2转发
|
||||
init();
|
||||
titleStreamC = StreamController<bool>();
|
||||
_titleStreamC = StreamController<bool>();
|
||||
if (action == 'comment') {
|
||||
_visibleTitle = true;
|
||||
titleStreamC.add(true);
|
||||
_titleStreamC.add(true);
|
||||
}
|
||||
|
||||
fabAnimationCtr = AnimationController(
|
||||
_fabAnimationCtr = AnimationController(
|
||||
vsync: this,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
);
|
||||
fabAnimationCtr.forward();
|
||||
_fabAnimationCtr?.forward();
|
||||
// 滚动事件监听
|
||||
scrollListener();
|
||||
}
|
||||
@@ -127,29 +126,31 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
|
||||
// 滑动事件监听
|
||||
void scrollListener() {
|
||||
scrollController = _dynamicDetailController.scrollController;
|
||||
scrollController.addListener(
|
||||
_dynamicDetailController.scrollController.addListener(
|
||||
() {
|
||||
// 分页加载
|
||||
if (scrollController.position.pixels >=
|
||||
scrollController.position.maxScrollExtent - 300) {
|
||||
if (_dynamicDetailController.scrollController.position.pixels >=
|
||||
_dynamicDetailController.scrollController.position.maxScrollExtent -
|
||||
300) {
|
||||
EasyThrottle.throttle('replylist', const Duration(seconds: 2), () {
|
||||
_dynamicDetailController.onLoadMore();
|
||||
});
|
||||
}
|
||||
|
||||
// 标题
|
||||
if (scrollController.offset > 55 && !_visibleTitle) {
|
||||
if (_dynamicDetailController.scrollController.offset > 55 &&
|
||||
!_visibleTitle) {
|
||||
_visibleTitle = true;
|
||||
titleStreamC.add(true);
|
||||
} else if (scrollController.offset <= 55 && _visibleTitle) {
|
||||
_titleStreamC.add(true);
|
||||
} else if (_dynamicDetailController.scrollController.offset <= 55 &&
|
||||
_visibleTitle) {
|
||||
_visibleTitle = false;
|
||||
titleStreamC.add(false);
|
||||
_titleStreamC.add(false);
|
||||
}
|
||||
|
||||
// fab按钮
|
||||
final ScrollDirection direction =
|
||||
scrollController.position.userScrollDirection;
|
||||
final ScrollDirection direction = _dynamicDetailController
|
||||
.scrollController.position.userScrollDirection;
|
||||
if (direction == ScrollDirection.forward) {
|
||||
_showFab();
|
||||
} else if (direction == ScrollDirection.reverse) {
|
||||
@@ -162,22 +163,23 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
void _showFab() {
|
||||
if (!_isFabVisible) {
|
||||
_isFabVisible = true;
|
||||
fabAnimationCtr.forward();
|
||||
_fabAnimationCtr?.forward();
|
||||
}
|
||||
}
|
||||
|
||||
void _hideFab() {
|
||||
if (_isFabVisible) {
|
||||
_isFabVisible = false;
|
||||
fabAnimationCtr.reverse();
|
||||
_fabAnimationCtr?.reverse();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
titleStreamC.close();
|
||||
fabAnimationCtr.dispose();
|
||||
scrollController.removeListener(() {});
|
||||
_titleStreamC.close();
|
||||
_fabAnimationCtr?.dispose();
|
||||
_fabAnimationCtr = null;
|
||||
_dynamicDetailController.scrollController.removeListener(() {});
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -186,7 +188,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: StreamBuilder(
|
||||
stream: titleStreamC.stream,
|
||||
stream: _titleStreamC.stream,
|
||||
initialData: false,
|
||||
builder: (context, AsyncSnapshot snapshot) {
|
||||
return AnimatedOpacity(
|
||||
@@ -212,7 +214,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
double padding = max(context.width / 2 - Grid.maxRowWidth, 0);
|
||||
if (orientation == Orientation.portrait) {
|
||||
return CustomScrollView(
|
||||
controller: scrollController,
|
||||
controller: _dynamicDetailController.scrollController,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
slivers: [
|
||||
SliverToBoxAdapter(
|
||||
@@ -252,7 +254,8 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
),
|
||||
Expanded(
|
||||
child: CustomScrollView(
|
||||
controller: scrollController,
|
||||
controller:
|
||||
_dynamicDetailController.scrollController,
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
slivers: [
|
||||
SliverPadding(
|
||||
@@ -276,6 +279,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
}
|
||||
},
|
||||
),
|
||||
if (_fabAnimationCtr != null)
|
||||
Positioned(
|
||||
bottom: MediaQuery.of(context).padding.bottom + 14,
|
||||
right: 14,
|
||||
@@ -284,7 +288,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||||
begin: const Offset(0, 2),
|
||||
end: const Offset(0, 0),
|
||||
).animate(CurvedAnimation(
|
||||
parent: fabAnimationCtr,
|
||||
parent: _fabAnimationCtr!,
|
||||
curve: Curves.easeInOut,
|
||||
)),
|
||||
child: FloatingActionButton(
|
||||
|
||||
@@ -118,9 +118,7 @@ class _DynamicsPageState extends State<DynamicsPage>
|
||||
@override
|
||||
void dispose() {
|
||||
_dynamicsController.tabController.removeListener(() {});
|
||||
_dynamicsController.tabController.dispose();
|
||||
_dynamicsController.scrollController.removeListener(() {});
|
||||
_dynamicsController.scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -114,14 +114,18 @@ class _EmotePanelState extends State<EmotePanel>
|
||||
SizedBox(height: MediaQuery.of(context).padding.bottom),
|
||||
],
|
||||
)
|
||||
: errorWidget(
|
||||
callback: _emotePanelController.onReload,
|
||||
),
|
||||
Error() => errorWidget(
|
||||
errMsg: loadingState.errMsg,
|
||||
callback: _emotePanelController.onReload,
|
||||
),
|
||||
: _errorWidget,
|
||||
Error() => _errorWidget,
|
||||
LoadingState() => throw UnimplementedError(),
|
||||
};
|
||||
}
|
||||
|
||||
Widget get _errorWidget => Center(
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
_emotePanelController.onReload();
|
||||
},
|
||||
icon: Icon(Icons.refresh),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -205,4 +205,10 @@ class HistoryController extends GetxController {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
scrollController.dispose();
|
||||
super.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,17 +21,16 @@ class HistoryPage extends StatefulWidget {
|
||||
class _HistoryPageState extends State<HistoryPage> {
|
||||
final HistoryController _historyController = Get.put(HistoryController());
|
||||
Future? _futureBuilderFuture;
|
||||
late ScrollController scrollController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_futureBuilderFuture = _historyController.queryHistoryList();
|
||||
scrollController = _historyController.scrollController;
|
||||
scrollController.addListener(
|
||||
_historyController.scrollController.addListener(
|
||||
() {
|
||||
if (scrollController.position.pixels >=
|
||||
scrollController.position.maxScrollExtent - 300) {
|
||||
if (_historyController.scrollController.position.pixels >=
|
||||
_historyController.scrollController.position.maxScrollExtent -
|
||||
300) {
|
||||
if (!_historyController.isLoadingMore.value) {
|
||||
EasyThrottle.throttle('history', const Duration(seconds: 1), () {
|
||||
_historyController.onLoad();
|
||||
@@ -61,8 +60,7 @@ class _HistoryPageState extends State<HistoryPage> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
scrollController.removeListener(() {});
|
||||
scrollController.dispose();
|
||||
_historyController.scrollController.removeListener(() {});
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -99,6 +99,7 @@ class HomeController extends GetxController with GetTickerProviderStateMixin {
|
||||
@override
|
||||
void dispose() {
|
||||
tabController.animation!.removeListener(() {});
|
||||
tabController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -64,4 +64,10 @@ class MemberArchiveController extends GetxController {
|
||||
Future onLoad() async {
|
||||
getMemberArchive('onLoad');
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
scrollController.dispose();
|
||||
super.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ class _MemberArchivePageState extends State<MemberArchivePage> {
|
||||
@override
|
||||
void dispose() {
|
||||
_memberArchivesController.scrollController.removeListener(() {});
|
||||
_memberArchivesController.scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -90,4 +90,11 @@ class MemberSearchController extends GetxController {
|
||||
onLoad() {
|
||||
searchArchives(type: 'onLoad');
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
searchFocusNode.dispose();
|
||||
scrollController.dispose();
|
||||
super.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,16 +20,14 @@ class _MemberSearchPageState extends State<MemberSearchPage>
|
||||
with SingleTickerProviderStateMixin {
|
||||
final MemberSearchController _memberSearchCtr =
|
||||
Get.put(MemberSearchController());
|
||||
late ScrollController scrollController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
scrollController = _memberSearchCtr.scrollController;
|
||||
scrollController.addListener(
|
||||
_memberSearchCtr.scrollController.addListener(
|
||||
() {
|
||||
if (scrollController.position.pixels >=
|
||||
scrollController.position.maxScrollExtent - 300) {
|
||||
if (_memberSearchCtr.scrollController.position.pixels >=
|
||||
_memberSearchCtr.scrollController.position.maxScrollExtent - 300) {
|
||||
EasyThrottle.throttle('history', const Duration(seconds: 1), () {
|
||||
_memberSearchCtr.onLoad();
|
||||
});
|
||||
@@ -42,9 +40,7 @@ class _MemberSearchPageState extends State<MemberSearchPage>
|
||||
@override
|
||||
void dispose() {
|
||||
// _tabController.dispose();
|
||||
_memberSearchCtr.searchFocusNode.dispose();
|
||||
scrollController.removeListener(() {});
|
||||
scrollController.dispose();
|
||||
_memberSearchCtr.scrollController.removeListener(() {});
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -94,7 +90,7 @@ class _MemberSearchPageState extends State<MemberSearchPage>
|
||||
}
|
||||
return CustomScrollView(
|
||||
physics: const AlwaysScrollableScrollPhysics(),
|
||||
controller: scrollController,
|
||||
controller: _memberSearchCtr.scrollController,
|
||||
slivers: <Widget>[
|
||||
FutureBuilder(
|
||||
future: _memberSearchCtr.searchArchives(),
|
||||
|
||||
@@ -44,4 +44,10 @@ class MemberSeasonsController extends GetxController {
|
||||
Future onLoad() async {
|
||||
getSeasonDetail('onLoad');
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
scrollController.dispose();
|
||||
super.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ class _MemberSeasonsPageState extends State<MemberSeasonsPage> {
|
||||
@override
|
||||
void dispose() {
|
||||
_memberSeasonsController.scrollController.removeListener(() {});
|
||||
_memberSeasonsController.scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -64,4 +64,10 @@ class RankController extends GetxController with GetTickerProviderStateMixin {
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
tabController.dispose();
|
||||
super.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,12 +23,6 @@ class _RankPageState extends State<RankPage>
|
||||
TabController(vsync: this, length: _rankController.tabs.length);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_rankController.tabController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
|
||||
@@ -130,4 +130,10 @@ class SSearchController extends GetxController {
|
||||
historyList.refresh();
|
||||
historyWord.put('cacheList', []);
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
searchFocusNode.dispose();
|
||||
super.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ class _SearchPageState extends State<SearchPage> with RouteAware {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_searchController.searchFocusNode.dispose();
|
||||
SearchPage.routeObserver.unsubscribe(this);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -83,4 +83,10 @@ class SubController extends GetxController {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
scrollController.dispose();
|
||||
super.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ class _SubPageState extends State<SubPage> {
|
||||
@override
|
||||
void dispose() {
|
||||
_subController.scrollController.removeListener(() {});
|
||||
_subController.scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ class _PagesPanelState extends State<PagesPanel> {
|
||||
// final String heroTag = Get.arguments['heroTag'];
|
||||
late final String heroTag;
|
||||
late VideoDetailController _videoDetailController;
|
||||
final ScrollController _scrollController2 = ScrollController();
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -50,9 +50,9 @@ class _PagesPanelState extends State<PagesPanel> {
|
||||
const double itemWidth = 150; // 每个列表项的宽度
|
||||
final double targetOffset = min(
|
||||
(currentIndex * itemWidth) - (itemWidth / 2),
|
||||
_scrollController2.position.maxScrollExtent);
|
||||
_scrollController.position.maxScrollExtent);
|
||||
// 滑动至目标位置
|
||||
_scrollController2.animateTo(
|
||||
_scrollController.animateTo(
|
||||
targetOffset,
|
||||
duration: const Duration(milliseconds: 300), // 滑动动画持续时间
|
||||
curve: Curves.easeInOut, // 滑动动画曲线
|
||||
@@ -62,7 +62,7 @@ class _PagesPanelState extends State<PagesPanel> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_scrollController2.dispose();
|
||||
_scrollController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ class _PagesPanelState extends State<PagesPanel> {
|
||||
height: 35,
|
||||
margin: const EdgeInsets.only(bottom: 8),
|
||||
child: ListView.builder(
|
||||
controller: _scrollController2,
|
||||
controller: _scrollController,
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: widget.pages.length,
|
||||
itemExtent: 150,
|
||||
|
||||
@@ -106,4 +106,10 @@ class WhisperDetailController extends GetxController {
|
||||
SmartDialog.showToast(result['msg']);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
replyContentController.dispose();
|
||||
super.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ class _WhisperDetailPageState extends State<WhisperDetailPage> {
|
||||
_readOnlyStream.close();
|
||||
_enableSend.close();
|
||||
_focusNode.dispose();
|
||||
_whisperDetailController.replyContentController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user