Riverpod是來自與Provider同一個開發者Remi,Riverpod是作者為了解決Provider一些的問題而開發出來的
我們都知道由於Provider是InheritedWidget的封裝,所以在讀取狀態時需要BuildContext。在開發時很容易在不理解InheritedWidget和BuildContext時,跨頁面獲取狀態經常會ProviderNotFoundException。
riverpod提供了三種方式來使用
我們這邊使用flutter + flutter_hooks的形式
pubspec.yaml
flutter_hooks: ^0.18.0
hooks_riverpod: ^2.0.0-dev.9
在widget tree的根部添加ProviderScope,用來儲存各種provider
這裡我們加入ProviderScope,並移除Provider
main.dart
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:todo/states/todo_state.dart';
import 'package:todo/ui/screens/nav_screen.dart';
void main() {
runApp(
ProviderScope(
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: NavScreen(),
debugShowCheckedModeBanner: false,
);
}
}
todo_state.dart
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:todo/models/todo_model.dart';
import 'package:todo/states/Itodo_state.dart';
class TodoState extends StateNotifier<List<TodoModel>> implements ITodoState {
TodoState() : super([]);
@override
List<TodoModel> getTodos() {
// TODO: implement getTodos
return state;
}
@override
void addTodo(TodoModel todo) {
// TODO: implement addTodo
state = [
...state,
todo,
];
}
}
final todosProvider = StateNotifierProvider<TodoState, List<TodoModel>>((ref) {
return TodoState();
});
lib\ui\widgets\todo_list_widget.dart:
import 'package:flutter/cupertino.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:todo/models/todo_model.dart';
import 'package:todo/states/todo_state.dart';
import 'package:todo/ui/widgets/todo_item_widget.dart';
class TodoList extends ConsumerWidget {
const TodoList({Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
List<TodoModel> todos = ref.watch(todosProvider);
return Column(
children: todos
.map(
(e) => TodoItem(title: e.title, done: e.done),
)
.toList(),
);
}
}
lib\ui\screens\home_screen.dart
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:todo/models/todo_model.dart';
import 'package:todo/states/todo_state.dart';
import 'package:todo/ui/widgets/todo_list_widget.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final TrackingScrollController _trackingScrollController =
TrackingScrollController();
@override
Widget build(BuildContext context) {
// final _todoState = Provider.of<TodoState>(context);
TodoModel testTodo = TodoModel(
title: "Just Test", done: false, date: DateTime.now().toString());
return CustomScrollView(
controller: _trackingScrollController,
slivers: [
SliverAppBar(
title: Text('Home Screen'),
),
SliverToBoxAdapter(
child: TodoList(),
),
SliverToBoxAdapter(child: AddTodo(testTodo)),
],
);
}
}
class AddTodo extends ConsumerWidget {
final TodoModel todo;
const AddTodo(this.todo, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
return ElevatedButton(
child: Text('Add todo test'),
onPressed: () {
ref.read(todosProvider.notifier).addTodo(todo);
},
);
}
}
今天簡單的介紹了Riverpod如何使用後,我們大致上了解如何使用狀態管理了,我們如果將裝置Restart會發現Todos會消失,我們接下來的目標是將我們的狀態給儲存起來,接下來會介紹如何持久的儲存我們的狀態