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();
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>
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,30 +279,31 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
}
},
),
Positioned(
bottom: MediaQuery.of(context).padding.bottom + 14,
right: 14,
child: SlideTransition(
position: Tween<Offset>(
begin: const Offset(0, 2),
end: const Offset(0, 0),
).animate(CurvedAnimation(
parent: fabAnimationCtr,
curve: Curves.easeInOut,
)),
child: FloatingActionButton(
heroTag: null,
onPressed: () {
feedBack();
dynamic oid = _dynamicDetailController.oid ??
IdUtils.bv2av(Get.parameters['bvid']!);
_dynamicDetailController.onReply(context, oid: oid);
},
tooltip: '评论动态',
child: const Icon(Icons.reply),
if (_fabAnimationCtr != null)
Positioned(
bottom: MediaQuery.of(context).padding.bottom + 14,
right: 14,
child: SlideTransition(
position: Tween<Offset>(
begin: const Offset(0, 2),
end: const Offset(0, 0),
).animate(CurvedAnimation(
parent: _fabAnimationCtr!,
curve: Curves.easeInOut,
)),
child: FloatingActionButton(
heroTag: null,
onPressed: () {
feedBack();
dynamic oid = _dynamicDetailController.oid ??
IdUtils.bv2av(Get.parameters['bvid']!);
_dynamicDetailController.onReply(context, oid: oid);
},
tooltip: '评论动态',
child: const Icon(Icons.reply),
),
),
),
),
],
),
),

View File

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

View File

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

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> {
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();
}

View File

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

View File

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

View File

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

View File

@@ -90,4 +90,11 @@ class MemberSearchController extends GetxController {
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 {
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(),

View File

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

View File

@@ -21,7 +21,6 @@ class _MemberSeasonsPageState extends State<MemberSeasonsPage> {
@override
void dispose() {
_memberSeasonsController.scrollController.removeListener(() {});
_memberSeasonsController.scrollController.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);
}
@override
void dispose() {
_rankController.tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
super.build(context);

View File

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

View File

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

View File

@@ -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,

View File

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

View File

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