feat(mobile-app): 为3个主导航页面添加下拉刷新功能

- TradingPage (兑换): 添加 RefreshIndicator,刷新时重新加载钱包和收益数据
- RankingPage (龙虎榜): 添加 RefreshIndicator,刷新时 invalidate leaderboardStatusProvider
  - 列表视图和待开启状态视图均支持下拉刷新
- MiningPage (监控): 使用 LayoutBuilder + IntrinsicHeight 模式实现
  - 刷新时并行加载用户数据、授权数据和钱包状态

注:ProfilePage 已有完整的下拉刷新实现,无需修改

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-02-05 21:50:43 -08:00
parent a1aba14ccf
commit 5bacd21840
3 changed files with 129 additions and 62 deletions

View File

@ -224,6 +224,16 @@ class _MiningPageState extends ConsumerState<MiningPage> {
); );
} }
///
Future<void> _onRefresh() async {
debugPrint('[MiningPage] 下拉刷新');
await Future.wait([
_loadUserData(),
_loadAuthorizationData(),
_checkWalletStatus(),
]);
}
/// ///
void _startMonitor() { void _startMonitor() {
setState(() { setState(() {
@ -268,18 +278,35 @@ class _MiningPageState extends ConsumerState<MiningPage> {
), ),
), ),
child: SafeArea( child: SafeArea(
child: Column( child: RefreshIndicator(
children: [ onRefresh: _onRefresh,
// color: const Color(0xFFD4AF37),
_buildAppBar(), backgroundColor: Colors.white,
// child: LayoutBuilder(
_buildUserInfo(), builder: (context, constraints) {
const SizedBox(height: 24), return SingleChildScrollView(
// physics: const AlwaysScrollableScrollPhysics(),
Expanded( child: ConstrainedBox(
child: _buildMiningStatusArea(), constraints: BoxConstraints(minHeight: constraints.maxHeight),
), child: IntrinsicHeight(
], child: Column(
children: [
//
_buildAppBar(),
//
_buildUserInfo(),
const SizedBox(height: 24),
//
Expanded(
child: _buildMiningStatusArea(),
),
],
),
),
),
);
},
),
), ),
), ),
), ),

View File

@ -88,6 +88,13 @@ class _RankingPageState extends ConsumerState<RankingPage> {
), ),
]; ];
///
Future<void> _onRefresh() async {
debugPrint('[RankingPage] 下拉刷新');
ref.invalidate(leaderboardStatusProvider);
// TODO: invalidate Provider
}
/// ///
void _selectRankingType(RankingType type) { void _selectRankingType(RankingType type) {
setState(() { setState(() {
@ -198,46 +205,61 @@ class _RankingPageState extends ConsumerState<RankingPage> {
break; break;
} }
return Center( return RefreshIndicator(
child: Column( onRefresh: _onRefresh,
mainAxisAlignment: MainAxisAlignment.center, color: const Color(0xFFD4AF37),
children: [ backgroundColor: Colors.white,
// child: LayoutBuilder(
Container( builder: (context, constraints) {
width: 80, return SingleChildScrollView(
height: 80, physics: const AlwaysScrollableScrollPhysics(),
decoration: BoxDecoration( child: ConstrainedBox(
color: const Color(0x1A8B5A2B), constraints: BoxConstraints(minHeight: constraints.maxHeight),
borderRadius: BorderRadius.circular(40), child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
//
Container(
width: 80,
height: 80,
decoration: BoxDecoration(
color: const Color(0x1A8B5A2B),
borderRadius: BorderRadius.circular(40),
),
child: const Icon(
Icons.hourglass_empty,
size: 40,
color: Color(0xFF8B5A2B),
),
),
const SizedBox(height: 24),
//
Text(
'$boardName待开启',
style: const TextStyle(
fontSize: 18,
fontFamily: 'Inter',
fontWeight: FontWeight.w700,
color: Color(0xFF5D4037),
),
),
const SizedBox(height: 8),
//
const Text(
'该榜单暂未开启,请稍后再来',
style: TextStyle(
fontSize: 14,
fontFamily: 'Inter',
color: Color(0xFF8B5A2B),
),
),
],
),
),
), ),
child: const Icon( );
Icons.hourglass_empty, },
size: 40,
color: Color(0xFF8B5A2B),
),
),
const SizedBox(height: 24),
//
Text(
'$boardName待开启',
style: const TextStyle(
fontSize: 18,
fontFamily: 'Inter',
fontWeight: FontWeight.w700,
color: Color(0xFF5D4037),
),
),
const SizedBox(height: 8),
//
const Text(
'该榜单暂未开启,请稍后再来',
style: TextStyle(
fontSize: 14,
fontFamily: 'Inter',
color: Color(0xFF8B5A2B),
),
),
],
), ),
); );
} }
@ -461,15 +483,21 @@ class _RankingPageState extends ConsumerState<RankingPage> {
/// ///
Widget _buildRankingList() { Widget _buildRankingList() {
return ListView.builder( return RefreshIndicator(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), onRefresh: _onRefresh,
itemCount: _mockRankingData.length, color: const Color(0xFFD4AF37),
itemBuilder: (context, index) { backgroundColor: Colors.white,
return Padding( child: ListView.builder(
padding: const EdgeInsets.only(bottom: 4), physics: const AlwaysScrollableScrollPhysics(),
child: _buildRankingItem(_mockRankingData[index]), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
); itemCount: _mockRankingData.length,
}, itemBuilder: (context, index) {
return Padding(
padding: const EdgeInsets.only(bottom: 4),
child: _buildRankingItem(_mockRankingData[index]),
);
},
),
); );
} }

View File

@ -218,6 +218,12 @@ class _TradingPageState extends ConsumerState<TradingPage> {
} }
} }
///
Future<void> _onRefresh() async {
debugPrint('[TradingPage] 下拉刷新');
await _loadWalletData();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@ -236,8 +242,13 @@ class _TradingPageState extends ConsumerState<TradingPage> {
), ),
), ),
child: SafeArea( child: SafeArea(
child: SingleChildScrollView( child: RefreshIndicator(
child: Column( onRefresh: _onRefresh,
color: const Color(0xFFD4AF37),
backgroundColor: Colors.white,
child: SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Column(
children: [ children: [
// //
_buildAppBar(), _buildAppBar(),
@ -273,6 +284,7 @@ class _TradingPageState extends ConsumerState<TradingPage> {
), ),
), ),
), ),
),
), ),
); );
} }