前言
Provider 是状态管理的官方推荐的状态管理的库.可以实现跨组件数据传输
pub地址:provider | Flutter package
github地址:https://github.com/rrousselGit/provider
Provider 是什么?
Provider
是一种依赖注入工具,用于在 Flutter widget 树中管理和共享状态。它基于 InheritedWidget
,通过将状态提升到应用程序顶层,解决了手动传递数据的复杂性。
核心组件
-
Provider
基础的依赖注入工具,常用的类型包括:ChangeNotifierProvider
Provider
FutureProvider
StreamProvider
ProxyProvider
-
ChangeNotifier
ChangeNotifier
是一个支持监听的类,提供了管理状态和通知更新的能力。 -
Consumer
Consumer
用于监听Provider
数据的变化,并更新 UI。 -
Selector
Selector
用于选择和监听数据中的某一部分,优化重建逻辑。
什么时候使用 Provider?
- 状态需要跨组件共享。
- 避免深层嵌套的数据传递(“prop drilling”)。
- 数据需要响应用户操作而更新。
使用方式
第一步:添加依赖
flutter pub add provider
第二步:设置 Provider
在应用顶层设置 Provider
。可以使用 MultiProvider
或单独的 ChangeNotifierProvider
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
// 启动应用
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => Counter()),
],
child: MyApp(),
),
);
}
// Counter 状态类
class Counter extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners(); // 通知 UI 更新
}
}
// 主应用
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
第三步:创建状态类
Provider
通常结合 ChangeNotifier
使用,状态类需要继承 ChangeNotifier
,并在状态发生变化时调用 notifyListeners()
通知监听器更新
class Counter extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners(); // 通知 UI 更新
}
}
第四步:使用状态
通过 Consumer
或 Provider.of
在 widget 树中使用状态数据。
使用 Consumer
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Provider Example")),
body: Center(
child: Consumer<Counter>(
builder: (context, counter, child) {
return Text(
'Count: ${counter.count}',
style: TextStyle(fontSize: 24),
);
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => context.read<Counter>().increment(),
child: Icon(Icons.add),
),
);
}
}
使用 Provider.of
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final counter = Provider.of<Counter>(context);
return Scaffold(
appBar: AppBar(title: Text("Provider Example")),
body: Center(
child: Text(
'Count: ${counter.count}',
style: TextStyle(fontSize: 24),
),
),
floatingActionButton: FloatingActionButton(
onPressed: counter.increment,
child: Icon(Icons.add),
),
);
}
}
进阶用法
1. 多个 Provider
当需要管理多个状态时,可以使用 MultiProvider
。
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => Counter()),
ChangeNotifierProvider(create: (_) => AnotherState()),
],
child: MyApp(),
);
2. 动态依赖注入
使用 ProxyProvider
动态注入其他 Provider
提供的依赖:
MultiProvider(
providers: [
Provider(create: (_) => Repository()),
ProxyProvider<Repository, Service>(
update: (context, repository, previousService) => Service(repository),
),
],
child: MyApp(),
);
3. 优化性能
使用 Selector
优化监听,避免不必要的 UI 重建:
Selector<Counter, int>(
selector: (context, counter) => counter.count,
builder: (context, count, child) {
return Text('Count: $count');
},
);