134 lines
3.5 KiB
Dart
134 lines
3.5 KiB
Dart
import 'package:blog_app/provider/blog.dart';
|
|
import 'package:blog_app/widget/common.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:blog_app/widget/easy_refresh.dart';
|
|
import 'package:blog_app/widget/blog.dart';
|
|
import 'package:easy_refresh/easy_refresh.dart';
|
|
|
|
class BlogPage extends StatefulWidget {
|
|
const BlogPage({super.key});
|
|
|
|
@override
|
|
State<BlogPage> createState() => _BlogPageState();
|
|
}
|
|
|
|
class _BlogPageState extends State<BlogPage> {
|
|
final EasyRefreshController _freshController = EasyRefreshController(
|
|
controlFinishRefresh: true,
|
|
controlFinishLoad: true,
|
|
);
|
|
final ScrollController _scrollController = ScrollController();
|
|
bool _showScrollToTop = false;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_scrollController.addListener(_onScroll);
|
|
// 初始化加载数据
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
context.read<BlogProvider>().refreshBlogList();
|
|
});
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_scrollController.removeListener(_onScroll);
|
|
_freshController.dispose();
|
|
_scrollController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
// 下拉刷新
|
|
Future<void> _onRefresh() async {
|
|
await context.read<BlogProvider>().refreshBlogList();
|
|
_freshController.finishRefresh();
|
|
}
|
|
|
|
// 上拉加载
|
|
Future<void> _onLoad() async {
|
|
final blogProvider = context.read<BlogProvider>();
|
|
if (blogProvider.hasMore) {
|
|
await blogProvider.loadMoreBlogList();
|
|
_freshController.finishLoad(IndicatorResult.success);
|
|
} else {
|
|
_freshController.finishLoad(IndicatorResult.noMore);
|
|
}
|
|
}
|
|
|
|
void _onScroll() {
|
|
// 当滚动距离超过300时显示返回顶部按钮
|
|
if (_scrollController.offset > 300) {
|
|
if (!_showScrollToTop) {
|
|
setState(() {
|
|
_showScrollToTop = true;
|
|
});
|
|
}
|
|
} else {
|
|
if (_showScrollToTop) {
|
|
setState(() {
|
|
_showScrollToTop = false;
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
// 滚动到顶部
|
|
void _scrollToTop() => scrollToTopAnimateTo(_scrollController);
|
|
|
|
Widget _buildBlogList(BlogProvider provider) {
|
|
if (provider.error != null) {
|
|
return buildErrorInfo(
|
|
errorInfo: provider.error!,
|
|
onPressed: () => provider.refreshBlogList,
|
|
);
|
|
}
|
|
|
|
return ListView.separated(
|
|
controller: _scrollController,
|
|
itemCount: provider.blogList.length,
|
|
itemBuilder: (context, index) {
|
|
final blog = provider.blogList[index];
|
|
return InkWell(
|
|
onTap: () => navigatorToBlogDetail(context, blog.id),
|
|
child: BlogCard(blog: blog),
|
|
);
|
|
},
|
|
separatorBuilder: (BuildContext context, int index) {
|
|
return SizedBox(height: 8);
|
|
},
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final blogProvider = context.watch<BlogProvider>();
|
|
|
|
return Stack(
|
|
children: [
|
|
Column(
|
|
children: [
|
|
Expanded(
|
|
child: buildEasyRefresh(
|
|
freshController: _freshController,
|
|
onRefresh: _onRefresh,
|
|
onLoad: _onLoad,
|
|
body: Stack(
|
|
children: [
|
|
if (blogProvider.isLoading)
|
|
buildLoadingIndicator()
|
|
else
|
|
_buildBlogList(blogProvider),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
if (_showScrollToTop)
|
|
buildScrollToTop(context: context, scrollToTop: _scrollToTop),
|
|
],
|
|
);
|
|
}
|
|
}
|