效果演示
![](https://img-blog.csdnimg.cn/2bf73cf32b03484ebad65861f478d9f1.gif)
需求说明
- 多个页面存在相同的
item
- 点击收藏时需要多个页面同时被收藏
- 局部刷新(仅刷新收藏
icon
)
字母后面的数字获取的是当前秒,为了验证是否是
局部刷新
实现方案
ChangeNotifierProvider
Selector
部分源码说明
关于状态管理ChangeNotifierProvider
的使用可以看这篇文章Flutter-状态管理-provider-ChangeNotifierProvider的用法
这里说明一下 Selector
的用法:
Selector
是provider
的消费者,需要说明的是我们平常使用最多的是Consumer
消费者,但是我们的需求是精准更新
,也就是说 Selector
有能够控制是否需要更新状态的能力
Selector({
Key? key,
required ValueWidgetBuilder<S> builder,
required S Function(BuildContext, A) selector,
ShouldRebuild<S>? shouldRebuild,
Widget? child,
}) : super(
key: key,
shouldRebuild: shouldRebuild,
builder: builder,
selector: (context) => selector(context, Provider.of(context)),
child: child,
);
核心代码:
Positioned(
child: Selector<AppRecipeModel, bool>(
builder: (BuildContext context, favourite, Widget? child) =>
IconButton(
icon: Icon(Icons.favorite,
color: favourite ? Colors.red : Colors.white),
onPressed: () {
model.favourite = !favourite;
context.read<AppRecipeModel>().toggle(model);
},
),
selector: (context, AppRecipeModel appRecipeModel) =>
appRecipeModel.indexRecipeModelList[index]
.favourite, //当favourite发生改变的时候会rebuild Selector的builder函数
),
right: 10.0,
top: 10.0)
AppRecipeModel:
class AppRecipeModel extends ChangeNotifier {
final List<RecipeModel> _indexRecipeModelList = [];
List<RecipeModel> get indexRecipeModelList => _indexRecipeModelList;
final List<RecipeModel> _exploreRecipeModelList = [];
List<RecipeModel> get exploreRecipeModelList => _exploreRecipeModelList;
toggle(RecipeModel recipeModel) {
for (var model in _indexRecipeModelList) {
if (model.recipeId == recipeModel.recipeId) {
model.favourite = recipeModel.favourite;
}
}
for (var model in _exploreRecipeModelList) {
if (model.recipeId == recipeModel.recipeId) {
model.favourite = recipeModel.favourite;
}
}
notifyListeners();
}
}
源码地址
更多详情信息请移步
我是源码