要很好的理解provider是怎么一回事,我们需要了解下面三个问题
- 谁是数据的提供者;
- 谁是数据的消费者;
- 谁是方法的调用者。
下面我们就一个待办事项app来了解provider。
-
首先创建一个空的flutter项目
然后创建一个数据模型 TodoModel实现
import 'package:flutter/foundation.dart';
class TodoModel with ChangeNotifier{
}
- 创建TodoEntity数据模型
class TodoEntity {
String name;
String title;
bool checked;
}
- 在TodoModel里面声明数据列表和添加方法及切换完成状态方法和移除方法
void addTodo(String title, String description) {
TodoEntity todoEntity = TodoEntity(title, description, false);
_list.add(todoEntity);
notifyListeners();
}
void toggleTodo(TodoEntity todoEntity) {
if (_list.contains(todoEntity)) {
todoEntity.checked = !todoEntity.checked;
notifyListeners();
}
}
bool removeTodo(TodoEntity todoEntity) {
_list.remove(todoEntity);
}
- 当然,我们要把我们的数据列表暴露出来给wiew
List<TodoEntity> _list = [];
List<TodoEntity> get todoList => _list;
- 现在,我们的TodoModel已经完成,完整代码如下:
class TodoModel with ChangeNotifier {
List<TodoEntity> _list = [];
List<TodoEntity> get todoList => _list;
void addTodo(String title, String description) {
TodoEntity todoEntity = TodoEntity(title, description, false);
_list.add(todoEntity);
notifyListeners();
}
void toggleTodo(TodoEntity todoEntity) {
if (_list.contains(todoEntity)) {
todoEntity.checked = !todoEntity.checked;
notifyListeners();
}
}
bool removeTodo(TodoEntity todoEntity) {
_list.remove(todoEntity);
}
}
- 现在我们创建数据的提供者
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider.value(
value: TodoModel(),
builder: (context, child) => MaterialApp(
title: 'todo',
theme: ThemeData.light(),
routes: {
'/todoList': (_) => TodoListPage(),
'/addTodo': (_) => AddTodoPage()
},
initialRoute: '/todoList',
),
);
}
}
使用ChangeNotifierProvider.value方法来提供我们的Model
- 创建我们的数据生产者
RaisedButton(
onPressed: () {
Provider.of<TodoModel>(context,listen: false)
.addTodo(_nameController.text, _descController.text);
Navigator.of(context).pop();
},
child: Text('添加'),
)
当按钮按下之后,往Model里面插入一条数据,使用Provider.of<TodoModel>(context,listen: false)来获取我们的Model,注意,这里的listen要赋值为false,我们不需要监听Model数据变化
- 创建我们的数据消费者
body: Consumer<TodoModel>(
builder: (context, model, child) {
return ListView.builder(
itemBuilder: (_, index) {
TodoEntity todoEntity = model.todoList[index];
return CheckboxListTile(
title: Text(todoEntity.title),
subtitle: Text(todoEntity.description),
value: todoEntity.checked,
onChanged: (value) => model.toggleTodo(todoEntity));
},
itemCount: model.todoList.length,
);
},
),
使用Consumer<TodoModel>来获取Model,当Model数据变化的时候,重构Consumer包裹的widget。