網路上中文資源有點少,只好看影片整理起來當 cheat sheet 用。
型別簡單、值不可被修改的 provider 。
final valueProvider = Provider<int>((ref) {
return 0;
});
型別簡單、值可被修改的 provider 。
final counterStateProvider = StateProvider<int>((ref) {
return 0;
});
型別複雜、值的修改方法可以自定義的 provider 。
class Clock extends StateNotifier<DateTime> {
Clock(): super(DateTime.now()) {
_timer = Timer.periodic(Duration(seconds: 1), (_) {
state = DateTime.now();
})
}
late final Timer _timer;
@override
void dispose() {
_timer.cancel();
super.dispose();
}
}
final clockProvider = StateNotifierProvider<Clock>((ref) {
return Clock();
});
當你的狀態來自於非同步的資料且你需要針對不同的狀態(loading, error, data) 加以區分時,這個 provider 幫你省去了一些麻煩。
class Book {
final String title;
final String author;
Record({
required this.title,
required this.author,
});
}
final bookShelfProvider = FutureProvider<List<Book>>((ref) {
return Future.value([
Book(
title: 'widget tree sucks',
author: 'lilybon',
),
Book(
title: 'use google to pass google interview, brilliant!',
author: 'google',
),
]);
});
final streamProvider = StreamProvider<int>((ref) {
return Stream.fromIterable([0, 1]);
});
未完成
未完成
未完成
以下範例用到的 provider 都可以從上面 Provider 類別介紹找到,就不再複製貼上了。
ConsumerWidget - 無狀態組件要用到 riverpod 的狀態管理時需繼承該類別。 ProviderListener - 適合監聽簡單的 state provider,若組件的業務邏輯過複雜則不適用。
class Counter extends ConsumerWidget {
@override
Widget build (BuildContext context, ScopedReader watch) {
final counter = watch(counterStateProvider);
return ProviderListener<StateController<int>>(
provider: counterStateProvider,
onChange: (context, counterState) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Value is ${counterState.state}')),
);
},
child: Scaffold(
body: Center(
child: Text(
'Value: ${counter.state}',
style: Theme.of(context).textTheme.headline4,
),
),
floatActionButton: FloatActionButton(
onPressed: () => context.read(counterStateProvider).state++
child: Icon(Icons.add),
)
),
);
}
}
class Timer extends ConsumerWidget {
@override
Widget build (BuildContext context, ScopedReader watch) {
final currentTime = watch(clockProvider.state);
final timeFormatted = DateFormat.Hms().format(currentTime);
return Scaffold(
body: Center(
child: Text(
timeFormatted,
style: Theme.of(context).textTheme.headline4,
),
),
);
}
}
class BookShelf extends ConsumerWidget {
@override
Widget build (BuildContext context, ScopedReader watch) {
final bookShelf = watch(bookShelfProvider);
return Scaffold(
body: Center(
// 可針對 future 的狀態作不同的渲染
child: bookShelf.when(
data: (books) => Column(
children: books.map((book) => Row(
children: [
Text(book.title),
Text(book.author),
],
)).toList()
),
loading: () => CircularProgressIndicator(),
error: (e, st) => Text('Error: $e'),
),
),
);
}
}
未完成
未完成
Flutter
Riverpod
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up