challenge_list_screen.dart 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // challenge_list_screen.dart
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter_riverpod/flutter_riverpod.dart';
  4. import 'package:japp_flutter/core/models/challenge_model.dart';
  5. import 'package:japp_flutter/features/challenge/view_models/challenge_list_vm.dart';
  6. import 'package:japp_flutter/features/challenge/views/widgets/challenge_list_card_widget.dart';
  7. class ChallengeListScreen extends ConsumerWidget {
  8. const ChallengeListScreen({super.key});
  9. @override
  10. Widget build(BuildContext context, WidgetRef ref) {
  11. final challengesState = ref.watch(challengeListProvider);
  12. return Scaffold(
  13. appBar: AppBar(
  14. title: const Text('挑战列表'),
  15. actions: [
  16. IconButton(
  17. icon: const Icon(Icons.refresh),
  18. onPressed: () => ref.read(challengeListProvider.notifier).refresh(),
  19. ),
  20. ],
  21. ),
  22. body: _buildBody(challengesState, ref),
  23. floatingActionButton: FloatingActionButton(
  24. onPressed: () => Navigator.pushNamed(context, '/challenge/add'),
  25. child: const Icon(Icons.add),
  26. ),
  27. );
  28. }
  29. Widget _buildBody(AsyncValue<List<ChallengeModel>> state, WidgetRef ref) {
  30. return state.when(
  31. loading: () => const Center(child: CircularProgressIndicator()),
  32. error: (error, stack) => Center(
  33. child: Column(
  34. mainAxisAlignment: MainAxisAlignment.center,
  35. children: [
  36. const Icon(Icons.error, color: Colors.red, size: 48),
  37. const SizedBox(height: 16),
  38. Text('加载失败: $error', style: const TextStyle(color: Colors.red)),
  39. const SizedBox(height: 16),
  40. ElevatedButton(
  41. onPressed: () =>
  42. ref.read(challengeListProvider.notifier).refresh(),
  43. child: const Text('重试'),
  44. ),
  45. ],
  46. ),
  47. ),
  48. data: (challenges) => challenges.isEmpty
  49. ? const Center(child: Text('暂无挑战', style: TextStyle(fontSize: 18)))
  50. : RefreshIndicator(
  51. onRefresh: () =>
  52. ref.read(challengeListProvider.notifier).refresh(),
  53. child: ListView.builder(
  54. padding: const EdgeInsets.all(16),
  55. itemCount: challenges.length,
  56. itemBuilder: (_, index) => ChallengeListCard(challenge: challenges[index]),
  57. // itemBuilder: (context, index) => ListTile(
  58. // title: Text(challenges[index].title),
  59. // // 其他列表项内容
  60. // ),
  61. ),
  62. ),
  63. );
  64. }
  65. }