-
Notifications
You must be signed in to change notification settings - Fork 2
/
main3.dart
122 lines (111 loc) · 3.9 KB
/
main3.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import 'package:easy_refresh/easy_refresh.dart';
import 'package:example/data/sample_item.dart';
import 'package:example/repository/sample_repository.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:riverpod_paging_utils/riverpod_paging_utils.dart';
import 'package:riverpod_paging_utils/theme_extension.dart';
part 'main3.g.dart';
void main() {
runApp(
const ProviderScope(
child: MainApp(),
),
);
}
class MainApp extends StatelessWidget {
const MainApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
extensions: [
PagingHelperViewTheme(
// disable pull-to-refresh
enableRefreshIndicator: false,
),
],
),
home: const SampleScreen(),
);
}
}
/// A Riverpod provider that mixes in [CursorPagingNotifierMixin].
/// This provider handles the pagination logic for fetching [SampleItem] data using cursor-based pagination.
@riverpod
class SampleNotifier extends _$SampleNotifier
with CursorPagingNotifierMixin<SampleItem> {
/// Builds the initial state of the provider by fetching data with a null cursor.
@override
Future<CursorPagingData<SampleItem>> build() => fetch(cursor: null);
/// Fetches paginated data from the [SampleRepository] based on the provided [cursor].
/// Returns a [CursorPagingData] object containing the fetched items, a flag indicating whether more data is available,
/// and the next cursor for fetching the next page.
@override
Future<CursorPagingData<SampleItem>> fetch({
required String? cursor,
}) async {
// Simulate a delay of 2 seconds to demonstrate the loading view.
await Future<void>.delayed(const Duration(seconds: 2));
final repository = ref.read(sampleRepositoryProvider);
final (items, nextCursor) = await repository.getByCursor(cursor);
final hasMore = nextCursor != null && nextCursor.isNotEmpty;
return CursorPagingData(
items: items,
hasMore: hasMore,
nextCursor: nextCursor,
);
}
}
/// A sample page that demonstrates the usage of [PagingHelperView] with the [SampleNotifier] provider.
class SampleScreen extends ConsumerWidget {
const SampleScreen({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
// Display errors using SnackBar
ref.listen(sampleNotifierProvider, (_, state) {
if (!state.isLoading && state.hasError) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
state.error!.toString(),
),
),
);
}
});
return Scaffold(
appBar: AppBar(
title: const Text('Advanced UI Customization'),
),
body: PagingHelperView(
provider: sampleNotifierProvider,
futureRefreshable: sampleNotifierProvider.future,
notifierRefreshable: sampleNotifierProvider.notifier,
contentBuilder: (data, widgetCount, endItemView) {
// Use EasyRefresh alternative to RefreshIndicator
return EasyRefresh(
onRefresh: () async => ref.refresh(sampleNotifierProvider.future),
child: ListView.builder(
itemCount: widgetCount,
itemBuilder: (context, index) {
// if the index is last, then
// return the end item view.
if (index == widgetCount - 1) {
return endItemView;
}
// Otherwise, build a list tile for each sample item.
return ListTile(
key: ValueKey(data.items[index].id),
title: Text(data.items[index].name),
subtitle: Text(data.items[index].id),
);
},
),
);
},
),
);
}
}