Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2024-11-22 18:50:07 +08:00
parent 64f66dd58f
commit 57b2f48c72
22 changed files with 134 additions and 88 deletions

View File

@@ -318,4 +318,11 @@ class DynamicsController extends GetxController
.animateToTop(); .animateToTop();
scrollController.animToTop(); scrollController.animToTop();
} }
@override
void onClose() {
tabController.dispose();
scrollController.dispose();
super.onClose();
}
} }

View File

@@ -32,9 +32,8 @@ class DynamicDetailPage extends StatefulWidget {
class _DynamicDetailPageState extends State<DynamicDetailPage> class _DynamicDetailPageState extends State<DynamicDetailPage>
with TickerProviderStateMixin { with TickerProviderStateMixin {
late DynamicDetailController _dynamicDetailController; late DynamicDetailController _dynamicDetailController;
late AnimationController fabAnimationCtr; AnimationController? _fabAnimationCtr;
late StreamController<bool> titleStreamC; // appBar title late StreamController<bool> _titleStreamC; // appBar title
late ScrollController scrollController;
bool _visibleTitle = false; bool _visibleTitle = false;
String? action; String? action;
// 回复类型 // 回复类型
@@ -49,17 +48,17 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
super.initState(); super.initState();
// floor 1原创 2转发 // floor 1原创 2转发
init(); init();
titleStreamC = StreamController<bool>(); _titleStreamC = StreamController<bool>();
if (action == 'comment') { if (action == 'comment') {
_visibleTitle = true; _visibleTitle = true;
titleStreamC.add(true); _titleStreamC.add(true);
} }
fabAnimationCtr = AnimationController( _fabAnimationCtr = AnimationController(
vsync: this, vsync: this,
duration: const Duration(milliseconds: 300), duration: const Duration(milliseconds: 300),
); );
fabAnimationCtr.forward(); _fabAnimationCtr?.forward();
// 滚动事件监听 // 滚动事件监听
scrollListener(); scrollListener();
} }
@@ -127,29 +126,31 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
// 滑动事件监听 // 滑动事件监听
void scrollListener() { void scrollListener() {
scrollController = _dynamicDetailController.scrollController; _dynamicDetailController.scrollController.addListener(
scrollController.addListener(
() { () {
// 分页加载 // 分页加载
if (scrollController.position.pixels >= if (_dynamicDetailController.scrollController.position.pixels >=
scrollController.position.maxScrollExtent - 300) { _dynamicDetailController.scrollController.position.maxScrollExtent -
300) {
EasyThrottle.throttle('replylist', const Duration(seconds: 2), () { EasyThrottle.throttle('replylist', const Duration(seconds: 2), () {
_dynamicDetailController.onLoadMore(); _dynamicDetailController.onLoadMore();
}); });
} }
// 标题 // 标题
if (scrollController.offset > 55 && !_visibleTitle) { if (_dynamicDetailController.scrollController.offset > 55 &&
!_visibleTitle) {
_visibleTitle = true; _visibleTitle = true;
titleStreamC.add(true); _titleStreamC.add(true);
} else if (scrollController.offset <= 55 && _visibleTitle) { } else if (_dynamicDetailController.scrollController.offset <= 55 &&
_visibleTitle) {
_visibleTitle = false; _visibleTitle = false;
titleStreamC.add(false); _titleStreamC.add(false);
} }
// fab按钮 // fab按钮
final ScrollDirection direction = final ScrollDirection direction = _dynamicDetailController
scrollController.position.userScrollDirection; .scrollController.position.userScrollDirection;
if (direction == ScrollDirection.forward) { if (direction == ScrollDirection.forward) {
_showFab(); _showFab();
} else if (direction == ScrollDirection.reverse) { } else if (direction == ScrollDirection.reverse) {
@@ -162,22 +163,23 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
void _showFab() { void _showFab() {
if (!_isFabVisible) { if (!_isFabVisible) {
_isFabVisible = true; _isFabVisible = true;
fabAnimationCtr.forward(); _fabAnimationCtr?.forward();
} }
} }
void _hideFab() { void _hideFab() {
if (_isFabVisible) { if (_isFabVisible) {
_isFabVisible = false; _isFabVisible = false;
fabAnimationCtr.reverse(); _fabAnimationCtr?.reverse();
} }
} }
@override @override
void dispose() { void dispose() {
titleStreamC.close(); _titleStreamC.close();
fabAnimationCtr.dispose(); _fabAnimationCtr?.dispose();
scrollController.removeListener(() {}); _fabAnimationCtr = null;
_dynamicDetailController.scrollController.removeListener(() {});
super.dispose(); super.dispose();
} }
@@ -186,7 +188,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: StreamBuilder( title: StreamBuilder(
stream: titleStreamC.stream, stream: _titleStreamC.stream,
initialData: false, initialData: false,
builder: (context, AsyncSnapshot snapshot) { builder: (context, AsyncSnapshot snapshot) {
return AnimatedOpacity( return AnimatedOpacity(
@@ -212,7 +214,7 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
double padding = max(context.width / 2 - Grid.maxRowWidth, 0); double padding = max(context.width / 2 - Grid.maxRowWidth, 0);
if (orientation == Orientation.portrait) { if (orientation == Orientation.portrait) {
return CustomScrollView( return CustomScrollView(
controller: scrollController, controller: _dynamicDetailController.scrollController,
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
slivers: [ slivers: [
SliverToBoxAdapter( SliverToBoxAdapter(
@@ -252,7 +254,8 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
), ),
Expanded( Expanded(
child: CustomScrollView( child: CustomScrollView(
controller: scrollController, controller:
_dynamicDetailController.scrollController,
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
slivers: [ slivers: [
SliverPadding( SliverPadding(
@@ -276,30 +279,31 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
} }
}, },
), ),
Positioned( if (_fabAnimationCtr != null)
bottom: MediaQuery.of(context).padding.bottom + 14, Positioned(
right: 14, bottom: MediaQuery.of(context).padding.bottom + 14,
child: SlideTransition( right: 14,
position: Tween<Offset>( child: SlideTransition(
begin: const Offset(0, 2), position: Tween<Offset>(
end: const Offset(0, 0), begin: const Offset(0, 2),
).animate(CurvedAnimation( end: const Offset(0, 0),
parent: fabAnimationCtr, ).animate(CurvedAnimation(
curve: Curves.easeInOut, parent: _fabAnimationCtr!,
)), curve: Curves.easeInOut,
child: FloatingActionButton( )),
heroTag: null, child: FloatingActionButton(
onPressed: () { heroTag: null,
feedBack(); onPressed: () {
dynamic oid = _dynamicDetailController.oid ?? feedBack();
IdUtils.bv2av(Get.parameters['bvid']!); dynamic oid = _dynamicDetailController.oid ??
_dynamicDetailController.onReply(context, oid: oid); IdUtils.bv2av(Get.parameters['bvid']!);
}, _dynamicDetailController.onReply(context, oid: oid);
tooltip: '评论动态', },
child: const Icon(Icons.reply), tooltip: '评论动态',
child: const Icon(Icons.reply),
),
), ),
), ),
),
], ],
), ),
), ),

View File

@@ -118,9 +118,7 @@ class _DynamicsPageState extends State<DynamicsPage>
@override @override
void dispose() { void dispose() {
_dynamicsController.tabController.removeListener(() {}); _dynamicsController.tabController.removeListener(() {});
_dynamicsController.tabController.dispose();
_dynamicsController.scrollController.removeListener(() {}); _dynamicsController.scrollController.removeListener(() {});
_dynamicsController.scrollController.dispose();
super.dispose(); super.dispose();
} }

View File

@@ -114,14 +114,18 @@ class _EmotePanelState extends State<EmotePanel>
SizedBox(height: MediaQuery.of(context).padding.bottom), SizedBox(height: MediaQuery.of(context).padding.bottom),
], ],
) )
: errorWidget( : _errorWidget,
callback: _emotePanelController.onReload, Error() => _errorWidget,
),
Error() => errorWidget(
errMsg: loadingState.errMsg,
callback: _emotePanelController.onReload,
),
LoadingState() => throw UnimplementedError(), LoadingState() => throw UnimplementedError(),
}; };
} }
Widget get _errorWidget => Center(
child: IconButton(
onPressed: () {
_emotePanelController.onReload();
},
icon: Icon(Icons.refresh),
),
);
} }

View File

@@ -205,4 +205,10 @@ class HistoryController extends GetxController {
}, },
); );
} }
@override
void onClose() {
scrollController.dispose();
super.onClose();
}
} }

View File

@@ -21,17 +21,16 @@ class HistoryPage extends StatefulWidget {
class _HistoryPageState extends State<HistoryPage> { class _HistoryPageState extends State<HistoryPage> {
final HistoryController _historyController = Get.put(HistoryController()); final HistoryController _historyController = Get.put(HistoryController());
Future? _futureBuilderFuture; Future? _futureBuilderFuture;
late ScrollController scrollController;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_futureBuilderFuture = _historyController.queryHistoryList(); _futureBuilderFuture = _historyController.queryHistoryList();
scrollController = _historyController.scrollController; _historyController.scrollController.addListener(
scrollController.addListener(
() { () {
if (scrollController.position.pixels >= if (_historyController.scrollController.position.pixels >=
scrollController.position.maxScrollExtent - 300) { _historyController.scrollController.position.maxScrollExtent -
300) {
if (!_historyController.isLoadingMore.value) { if (!_historyController.isLoadingMore.value) {
EasyThrottle.throttle('history', const Duration(seconds: 1), () { EasyThrottle.throttle('history', const Duration(seconds: 1), () {
_historyController.onLoad(); _historyController.onLoad();
@@ -61,8 +60,7 @@ class _HistoryPageState extends State<HistoryPage> {
@override @override
void dispose() { void dispose() {
scrollController.removeListener(() {}); _historyController.scrollController.removeListener(() {});
scrollController.dispose();
super.dispose(); super.dispose();
} }

View File

@@ -99,6 +99,7 @@ class HomeController extends GetxController with GetTickerProviderStateMixin {
@override @override
void dispose() { void dispose() {
tabController.animation!.removeListener(() {}); tabController.animation!.removeListener(() {});
tabController.dispose();
super.dispose(); super.dispose();
} }

View File

@@ -64,4 +64,10 @@ class MemberArchiveController extends GetxController {
Future onLoad() async { Future onLoad() async {
getMemberArchive('onLoad'); getMemberArchive('onLoad');
} }
@override
void onClose() {
scrollController.dispose();
super.onClose();
}
} }

View File

@@ -23,7 +23,6 @@ class _MemberArchivePageState extends State<MemberArchivePage> {
@override @override
void dispose() { void dispose() {
_memberArchivesController.scrollController.removeListener(() {}); _memberArchivesController.scrollController.removeListener(() {});
_memberArchivesController.scrollController.dispose();
super.dispose(); super.dispose();
} }

View File

@@ -90,4 +90,11 @@ class MemberSearchController extends GetxController {
onLoad() { onLoad() {
searchArchives(type: 'onLoad'); searchArchives(type: 'onLoad');
} }
@override
void onClose() {
searchFocusNode.dispose();
scrollController.dispose();
super.onClose();
}
} }

View File

@@ -20,16 +20,14 @@ class _MemberSearchPageState extends State<MemberSearchPage>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
final MemberSearchController _memberSearchCtr = final MemberSearchController _memberSearchCtr =
Get.put(MemberSearchController()); Get.put(MemberSearchController());
late ScrollController scrollController;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
scrollController = _memberSearchCtr.scrollController; _memberSearchCtr.scrollController.addListener(
scrollController.addListener(
() { () {
if (scrollController.position.pixels >= if (_memberSearchCtr.scrollController.position.pixels >=
scrollController.position.maxScrollExtent - 300) { _memberSearchCtr.scrollController.position.maxScrollExtent - 300) {
EasyThrottle.throttle('history', const Duration(seconds: 1), () { EasyThrottle.throttle('history', const Duration(seconds: 1), () {
_memberSearchCtr.onLoad(); _memberSearchCtr.onLoad();
}); });
@@ -42,9 +40,7 @@ class _MemberSearchPageState extends State<MemberSearchPage>
@override @override
void dispose() { void dispose() {
// _tabController.dispose(); // _tabController.dispose();
_memberSearchCtr.searchFocusNode.dispose(); _memberSearchCtr.scrollController.removeListener(() {});
scrollController.removeListener(() {});
scrollController.dispose();
super.dispose(); super.dispose();
} }
@@ -94,7 +90,7 @@ class _MemberSearchPageState extends State<MemberSearchPage>
} }
return CustomScrollView( return CustomScrollView(
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
controller: scrollController, controller: _memberSearchCtr.scrollController,
slivers: <Widget>[ slivers: <Widget>[
FutureBuilder( FutureBuilder(
future: _memberSearchCtr.searchArchives(), future: _memberSearchCtr.searchArchives(),

View File

@@ -44,4 +44,10 @@ class MemberSeasonsController extends GetxController {
Future onLoad() async { Future onLoad() async {
getSeasonDetail('onLoad'); getSeasonDetail('onLoad');
} }
@override
void onClose() {
scrollController.dispose();
super.onClose();
}
} }

View File

@@ -21,7 +21,6 @@ class _MemberSeasonsPageState extends State<MemberSeasonsPage> {
@override @override
void dispose() { void dispose() {
_memberSeasonsController.scrollController.removeListener(() {}); _memberSeasonsController.scrollController.removeListener(() {});
_memberSeasonsController.scrollController.dispose();
super.dispose(); super.dispose();
} }

View File

@@ -64,4 +64,10 @@ class RankController extends GetxController with GetTickerProviderStateMixin {
// }); // });
// } // }
} }
@override
void onClose() {
tabController.dispose();
super.onClose();
}
} }

View File

@@ -23,12 +23,6 @@ class _RankPageState extends State<RankPage>
TabController(vsync: this, length: _rankController.tabs.length); TabController(vsync: this, length: _rankController.tabs.length);
} }
@override
void dispose() {
_rankController.tabController.dispose();
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
super.build(context); super.build(context);

View File

@@ -130,4 +130,10 @@ class SSearchController extends GetxController {
historyList.refresh(); historyList.refresh();
historyWord.put('cacheList', []); historyWord.put('cacheList', []);
} }
@override
void onClose() {
searchFocusNode.dispose();
super.onClose();
}
} }

View File

@@ -26,7 +26,6 @@ class _SearchPageState extends State<SearchPage> with RouteAware {
@override @override
void dispose() { void dispose() {
_searchController.searchFocusNode.dispose();
SearchPage.routeObserver.unsubscribe(this); SearchPage.routeObserver.unsubscribe(this);
super.dispose(); super.dispose();
} }

View File

@@ -83,4 +83,10 @@ class SubController extends GetxController {
), ),
); );
} }
@override
void onClose() {
scrollController.dispose();
super.onClose();
}
} }

View File

@@ -21,7 +21,6 @@ class _SubPageState extends State<SubPage> {
@override @override
void dispose() { void dispose() {
_subController.scrollController.removeListener(() {}); _subController.scrollController.removeListener(() {});
_subController.scrollController.dispose();
super.dispose(); super.dispose();
} }

View File

@@ -34,7 +34,7 @@ class _PagesPanelState extends State<PagesPanel> {
// final String heroTag = Get.arguments['heroTag']; // final String heroTag = Get.arguments['heroTag'];
late final String heroTag; late final String heroTag;
late VideoDetailController _videoDetailController; late VideoDetailController _videoDetailController;
final ScrollController _scrollController2 = ScrollController(); final ScrollController _scrollController = ScrollController();
@override @override
void initState() { void initState() {
@@ -50,9 +50,9 @@ class _PagesPanelState extends State<PagesPanel> {
const double itemWidth = 150; // 每个列表项的宽度 const double itemWidth = 150; // 每个列表项的宽度
final double targetOffset = min( final double targetOffset = min(
(currentIndex * itemWidth) - (itemWidth / 2), (currentIndex * itemWidth) - (itemWidth / 2),
_scrollController2.position.maxScrollExtent); _scrollController.position.maxScrollExtent);
// 滑动至目标位置 // 滑动至目标位置
_scrollController2.animateTo( _scrollController.animateTo(
targetOffset, targetOffset,
duration: const Duration(milliseconds: 300), // 滑动动画持续时间 duration: const Duration(milliseconds: 300), // 滑动动画持续时间
curve: Curves.easeInOut, // 滑动动画曲线 curve: Curves.easeInOut, // 滑动动画曲线
@@ -62,7 +62,7 @@ class _PagesPanelState extends State<PagesPanel> {
@override @override
void dispose() { void dispose() {
_scrollController2.dispose(); _scrollController.dispose();
super.dispose(); super.dispose();
} }
@@ -114,7 +114,7 @@ class _PagesPanelState extends State<PagesPanel> {
height: 35, height: 35,
margin: const EdgeInsets.only(bottom: 8), margin: const EdgeInsets.only(bottom: 8),
child: ListView.builder( child: ListView.builder(
controller: _scrollController2, controller: _scrollController,
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
itemCount: widget.pages.length, itemCount: widget.pages.length,
itemExtent: 150, itemExtent: 150,

View File

@@ -106,4 +106,10 @@ class WhisperDetailController extends GetxController {
SmartDialog.showToast(result['msg']); SmartDialog.showToast(result['msg']);
} }
} }
@override
void onClose() {
replyContentController.dispose();
super.onClose();
}
} }

View File

@@ -46,7 +46,6 @@ class _WhisperDetailPageState extends State<WhisperDetailPage> {
_readOnlyStream.close(); _readOnlyStream.close();
_enableSend.close(); _enableSend.close();
_focusNode.dispose(); _focusNode.dispose();
_whisperDetailController.replyContentController.dispose();
super.dispose(); super.dispose();
} }