8、Flutter状态管理provider用法
之前学习Flutter,跟网上大神教程写了一个购物的APP,里面提供的状态管理工具是provide,几个月过后,Flutter官方发布provider代替provide,成为最新的状态管理工具,例外,新的provider支持Flutter_web的开发,亲测好用。
用法:
1、在项目的 pubspec.yml 添加 provider
dependencies:
provider: ^3.1.0
2、构建混合ChangeNotifier的类,操作全局数据,使用notifyListeners方法来通知 UI 更新:
如:底部导航切换,定义当前切换卡索引--currentIndex,更改currentIndex的值,通知主页刷新底部导航UI,切换当前页面。
import 'package:flutter/foundation.dart';
class CurrentIndexProvide with ChangeNotifier{
int currentIndex = 0;
changeIndex(int newIndex){
currentIndex = newIndex;
notifyListeners();
}
}
要使用这个ChangeNotifier状态管理类,需要用 provider 提供的 ChangeNotifierProvider 方法将数据注册到整个应用。如果有多个这样的ChangeNotifier状态管理类,就需要使用MultiProvider,用法介绍:
import 'package:flutter/material.dart';
import 'pages/index_page.dart';
import 'package:provider/provider.dart';
......
import 'provide/currentIndex.dart';
void main(){
List<SingleChildCloneableWidget> provides = [];
provides..add(ChangeNotifierProvider.value(value:ChildCategory()))
..add(ChangeNotifierProvider.value(value:CategoryGoodsListProvider()))
..add(ChangeNotifierProvider.value(value:DetailInfoProvide()))
..add(ChangeNotifierProvider.value(value:CartProvide()))
..add(ChangeNotifierProvider.value(value:CurrentIndexProvide()));//本文中重点介绍
runApp(MultiProvider(providers: provides,child:MyApp()));
}
class MyApp extends StatelessWidget{
......
}
3、ChangeNotifierProvider 方法将数据注册到整个应用
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'pages/index_page.dart';
import 'provide/currentIndex.dart';
class MyApp extends StatelessWidget{
@override
Widget build(BuildContext context) {
final router = Router();
Routers.configureRouters(router);
Application.router = router;
return Container(
child: MaterialApp(
title: '商城',
onGenerateRoute: Application.router.generator,
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.pink,
),
home: ChangeNotifierProvider(
builder: (context) =>CurrentIndexProvide(),
child: IndexPage(),
),
);
}
}
然后IndexPage中,使用CurrentIndexProvide中的currentIndex。
4、使用 provider 的数据首先要导入 provider 以及对应的currentIndex CurrentIndexProvide,然后用 Consumer 加类型 CurrentIndexProvide 来使用这个currentIndex
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'home_page.dart';
import 'category_page.dart';
import 'cart_page.dart';
import 'member_page.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:provider/provider.dart';
import '../provide/currentIndex.dart';
class IndexPage extends StatelessWidget {
final List<BottomNavigationBarItem> bottomTabs=[
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.home),
title: Text('首页'),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.search),
title: Text('分类'),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.shopping_cart),
title: Text('购物车'),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.profile_circled),
title: Text('会员中心'),
),
];
final List<Widget> tabBodies = [
HomePage(),
CategoryPage(),
CartPage(),
MemberPage()
];
@override
Widget build(BuildContext context) {
ScreenUtil.instance = ScreenUtil(width: 750,height: 1334)..init(context);
return Consumer<CurrentIndexProvide>(
builder: (context, currentIndexProvide, child){
int currentIndex = currentIndexProvide.currentIndex;
return Scaffold(
backgroundColor: Color.fromRGBO(244, 245, 245, 1.0),
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: currentIndex,
items: bottomTabs,
onTap: (index){ //切换导航卡
currentIndexProvide.changeIndex(index);
},
),
body: IndexedStack(
index: currentIndex,
children: tabBodies,
)
);
},
);
}
}
最后,当切换导航卡,通过调用CurrentIndexProvide中的changeIndex(index)方法,changeIndex(int newIndex){
currentIndex = newIndex; //修改状态管理中的currentIndex
notifyListeners(); // 刷新UI
}
notifyListeners() : 通知代码中使用到此provider的控件Consumer进行刷新