|
|
|
@ -37,101 +37,117 @@ class _RecommendTabState extends State<RecommendTab> |
|
|
|
final bottomPadding = MediaQuery.of(context).padding.bottom; |
|
|
|
final tabBarHeight = 64.0; |
|
|
|
final totalBottomPadding = bottomPadding + tabBarHeight; |
|
|
|
return SizedBox( |
|
|
|
height: MediaQuery.of(context).size.height - totalBottomPadding, |
|
|
|
child: Obx(() { |
|
|
|
final List<MarriageData> dataSource = controller.recommendFeed; |
|
|
|
|
|
|
|
return Obx(() { |
|
|
|
final List<MarriageData> dataSource = controller.recommendFeed; |
|
|
|
final bool hasMore = controller.recommendHasMore.value; |
|
|
|
|
|
|
|
return SmartRefresher( |
|
|
|
controller: _refreshController, |
|
|
|
enablePullDown: true, |
|
|
|
enablePullUp: true, |
|
|
|
header: const ClassicHeader( |
|
|
|
refreshingText: '正在刷新...', |
|
|
|
completeText: '刷新完成', |
|
|
|
idleText: '下拉刷新', |
|
|
|
releaseText: '释放刷新', |
|
|
|
), |
|
|
|
footer: ClassicFooter( |
|
|
|
idleText: '上拉加载', |
|
|
|
loadingText: '正在加载...', |
|
|
|
noDataText: '没有更多数据', |
|
|
|
canLoadingText: '释放加载', |
|
|
|
), |
|
|
|
// 下拉刷新 |
|
|
|
onRefresh: () async { |
|
|
|
print('推荐列表下拉刷新被触发'); |
|
|
|
try { |
|
|
|
await controller.refreshRecommendData(); |
|
|
|
_refreshController.refreshCompleted(); |
|
|
|
print('推荐列表刷新完成'); |
|
|
|
} catch (e) { |
|
|
|
print('推荐列表刷新失败: $e'); |
|
|
|
_refreshController.refreshFailed(); |
|
|
|
} |
|
|
|
}, |
|
|
|
// 上拉加载更多 |
|
|
|
onLoading: () async { |
|
|
|
print('推荐列表上拉加载被触发, hasMore: $hasMore'); |
|
|
|
if (hasMore && controller.recommendHasMore.value) { |
|
|
|
try { |
|
|
|
await controller.loadRecommendMoreData(); |
|
|
|
// 完成加载,根据是否有更多数据决定 |
|
|
|
if (controller.recommendHasMore.value) { |
|
|
|
_refreshController.loadComplete(); |
|
|
|
print('推荐列表加载更多成功'); |
|
|
|
} else { |
|
|
|
_refreshController.loadNoData(); |
|
|
|
print('推荐列表没有更多数据了'); |
|
|
|
} |
|
|
|
} catch (e) { |
|
|
|
print('推荐列表加载更多失败: $e'); |
|
|
|
_refreshController.loadFailed(); |
|
|
|
} |
|
|
|
} else { |
|
|
|
_refreshController.loadNoData(); |
|
|
|
print('推荐列表没有更多数据'); |
|
|
|
} |
|
|
|
}, |
|
|
|
child: ListView.separated( |
|
|
|
// 关键:始终允许滚动,即使内容不足 |
|
|
|
physics: const AlwaysScrollableScrollPhysics( |
|
|
|
parent: BouncingScrollPhysics(), |
|
|
|
return SmartRefresher( |
|
|
|
controller: _refreshController, |
|
|
|
enablePullDown: true, |
|
|
|
enablePullUp: true, |
|
|
|
physics: const ClampingScrollPhysics(), |
|
|
|
header: const ClassicHeader( |
|
|
|
refreshingText: '正在刷新...', |
|
|
|
completeText: '刷新完成', |
|
|
|
idleText: '下拉刷新', |
|
|
|
releaseText: '释放刷新', |
|
|
|
), |
|
|
|
// 移除顶部 padding,让刷新指示器可以正确显示在 AppBar 下方 |
|
|
|
padding: EdgeInsets.only( |
|
|
|
left: 12, |
|
|
|
right: 12, |
|
|
|
bottom: totalBottomPadding + 12, |
|
|
|
footer: ClassicFooter( |
|
|
|
idleText: '上拉加载', |
|
|
|
loadingText: '正在加载...', |
|
|
|
noDataText: '没有更多数据', |
|
|
|
canLoadingText: '释放加载', |
|
|
|
), |
|
|
|
itemBuilder: (context, index) { |
|
|
|
// 空数据状态 |
|
|
|
if (dataSource.isEmpty && index == 0) { |
|
|
|
// 使用足够的高度确保可以滚动 |
|
|
|
return SizedBox( |
|
|
|
height: MediaQuery.of(context).size.height * 1.2, |
|
|
|
child: const Center( |
|
|
|
child: Text( |
|
|
|
"暂无数据", |
|
|
|
style: TextStyle(fontSize: 14, color: Color(0xFF999999)), |
|
|
|
), |
|
|
|
), |
|
|
|
); |
|
|
|
// 下拉刷新 |
|
|
|
onRefresh: () async { |
|
|
|
print('推荐列表下拉刷新被触发'); |
|
|
|
try { |
|
|
|
await controller.refreshRecommendData(); |
|
|
|
print('推荐列表刷新完成, hasMore: $controller.recommendHasMore.value'); |
|
|
|
_refreshController.refreshCompleted(); |
|
|
|
_refreshController.loadComplete(); |
|
|
|
} catch (e) { |
|
|
|
print('推荐列表刷新失败: $e'); |
|
|
|
_refreshController.refreshFailed(); |
|
|
|
} |
|
|
|
// 数据项 |
|
|
|
final item = dataSource[index]; |
|
|
|
return ContentCard(item: item); |
|
|
|
}, |
|
|
|
separatorBuilder: (context, index) { |
|
|
|
// 空状态或加载状态时不显示分隔符 |
|
|
|
if (dataSource.isEmpty) return const SizedBox.shrink(); |
|
|
|
return const SizedBox(height: 12); |
|
|
|
// 上拉加载更多 |
|
|
|
onLoading: () async { |
|
|
|
print('推荐列表上拉加载被触发, hasMore: $controller.recommendHasMore.value'); |
|
|
|
if (controller.recommendHasMore.value) { |
|
|
|
try { |
|
|
|
await controller.loadRecommendMoreData(); |
|
|
|
// 完成加载,根据是否有更多数据决定 |
|
|
|
if (controller.recommendHasMore.value) { |
|
|
|
_refreshController.loadComplete(); |
|
|
|
print('推荐列表加载更多成功'); |
|
|
|
} else { |
|
|
|
_refreshController.loadNoData(); |
|
|
|
print('推荐列表没有更多数据了'); |
|
|
|
} |
|
|
|
} catch (e) { |
|
|
|
print('推荐列表加载更多失败: $e'); |
|
|
|
_refreshController.loadFailed(); |
|
|
|
} |
|
|
|
} else { |
|
|
|
_refreshController.loadNoData(); |
|
|
|
print('推荐列表没有更多数据'); |
|
|
|
} |
|
|
|
}, |
|
|
|
// 至少显示一个 item(用于显示加载或空状态) |
|
|
|
itemCount: dataSource.isEmpty ? 1 : dataSource.length, |
|
|
|
), |
|
|
|
); |
|
|
|
}); |
|
|
|
child: ListView.separated( |
|
|
|
// 关键:始终允许滚动,即使内容不足 |
|
|
|
// 移除顶部 padding,让刷新指示器可以正确显示在 AppBar 下方 |
|
|
|
padding: EdgeInsets.only( |
|
|
|
left: 12, |
|
|
|
right: 12, |
|
|
|
bottom: 12, |
|
|
|
), |
|
|
|
itemBuilder: (context, index) { |
|
|
|
// 空数据状态 |
|
|
|
if (dataSource.isEmpty && index == 0) { |
|
|
|
// 使用足够的高度确保可以滚动 |
|
|
|
if(controller.recommendIsLoading.value){ |
|
|
|
return SizedBox( |
|
|
|
height: MediaQuery.of(context).size.height - totalBottomPadding, |
|
|
|
child: Center( |
|
|
|
child: Column( |
|
|
|
mainAxisAlignment: MainAxisAlignment.center, |
|
|
|
children: [ |
|
|
|
CircularProgressIndicator(), |
|
|
|
SizedBox(height: 16), |
|
|
|
Text('加载数据中...'), |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
); |
|
|
|
} else { |
|
|
|
return SizedBox( |
|
|
|
height: MediaQuery.of(context).size.height - totalBottomPadding, |
|
|
|
child: const Center( |
|
|
|
child: Text( |
|
|
|
"暂无数据", |
|
|
|
style: TextStyle(fontSize: 14, color: Color(0xFF999999)), |
|
|
|
), |
|
|
|
), |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
// 数据项 |
|
|
|
final item = dataSource[index]; |
|
|
|
return ContentCard(item: item); |
|
|
|
}, |
|
|
|
separatorBuilder: (context, index) { |
|
|
|
// 空状态或加载状态时不显示分隔符 |
|
|
|
if (dataSource.isEmpty) return const SizedBox.shrink(); |
|
|
|
return const SizedBox(height: 12); |
|
|
|
}, |
|
|
|
// 至少显示一个 item(用于显示加载或空状态) |
|
|
|
itemCount: dataSource.isEmpty ? 1 : dataSource.length, |
|
|
|
), |
|
|
|
); |
|
|
|
}), |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
@override |
|
|
|
|