provider 包是一个易于使用的包,它基本上是对 InheritedWidgets 的包装,使其更易于使用和管理。它提供了一种状态管理技术,用于管理应用程序周围的一段数据。
提供程序包中可用的基本类是——
- ChangeNotifierProvider
它侦听由模型类扩展的 ChangeNotifier,将其公开给其子类和后代,并在调用 notifyListeners时重建依赖。
ChangeNotifierProvider(
create: (context) => DataModel(),
child: ...
)
- Consumer
它从其祖先那里获取提供者,并将获取的值传递给构建者。
@override
Widget build(BuildContext context) {
return Consumer(
builder: (context, data, child) => DataWidget(par1: par1, par2: par2),
child: Text(data.first),
);
}
- FutureProvider
此类侦听Future ,然后将其值传递给其子代和后代。
Constructors
FutureProvider(
{Key key,
@required Create> create,
T initialData,
ErrorBuilder catchError,
UpdateShouldNotify updateShouldNotify,
bool lazy,
TransitionBuilder builder,
Widget child}
)
This creates a Future from create and subscribes to it.
FutureProvider.value(
{Key key,
@required Future value,
T initialData,
ErrorBuilder catchError,
UpdateShouldNotify updateShouldNotify,
TransitionBuilder builder,
Widget child}
)
This constructor notifies the changed values to the FutureProvider children.
Ex: FutureProvider(create: (context) =>
Model(),)
- InheritedProvider
的InheritedProvider提供InheritedWidget的一般实现。 - MultiProvider一种用于同时提供多个类的提供者。
MultiProvider(
providers: [
Provider(create: (context) => Model1()),
StreamProvider(create: (context) => Model2()),
FutureProvider(create: (context) => Model3()),
],
child: someWidget,
)
- Provider
是基本的提供者。 - ProxyProvider
此提供程序依赖于其他提供程序的价值。该值可由创建或更新使用。
Constructor
ProxyProvider(
{Key key,
Create create,
@required ProxyProviderBuilder update,
UpdateShouldNotify updateShouldNotify,
Dispose dispose, bool lazy,
TransitionBuilder builder,
Widget child}
)
This initializes key for subclasses.
- StreamProvider
此类侦听 Stream,然后将其值传递给其子级和后代。这可以用作
Constructors
StreamProvider(
{Key key,
@required Create> create,
T initialData,
ErrorBuilder catchError,
UpdateShouldNotify updateShouldNotify,
bool lazy,
TransitionBuilder builder,
Widget child}
)
This creates a stream using create and subscribes to it.
StreamProvider.value(
{Key key,
@required Stream value,
T initialData,
ErrorBuilder catchError,
UpdateShouldNotify updateShouldNotify,
bool lazy,
TransitionBuilder builder,
Widget child}
)
This constructor notifies the changed values to the StreamProvider children.
Ex: StreamProvider(create: (context) =>
Model(),)
- ValueListenableProvider
此类通过订阅 ValueListenable 来接收值的更改。
ValueListenableProvider.value(
{Key key,
@required ValueListenable value,
UpdateShouldNotify updateShouldNotify,
TransitionBuilder builder,
Widget child}
)
This constructor shows the changed values to its children.
除此之外,还有许多其他类可根据需要使用,但这些是最常用的类。
要使用提供程序包,我们需要将提供程序包添加到 pubspec.yaml 的依赖项部分,然后单击获取按钮以获取依赖项。
dependencies:
flutter:
sdk: flutter
provider: ^4.3.2+4 #ADD
我们将查看一个简单的示例应用程序
首先,我们将在 lib 文件夹内定义一个模型库,该文件夹由 item 组成。 dart和 item_data。dart。除此之外,lib 还有 3 个dart文件,即dart文件。dart,回家。 dart和 item_list。dart。
项。 dart是一个简单的类,它定义了 item 类将拥有的属性和切换方法。
Dart
import 'package:flutter/foundation.dart';
class Item {
String item;
bool completed;
Item({@required this.item, this.completed = false});
void toggle() {
completed = !completed;
}
}
Dart
import 'dart:collection';
import 'package:flutter/foundation.dart';
import '../model/item.dart';
class ItemData with ChangeNotifier {
List- _items = [];
UnmodifiableListView
- get items => UnmodifiableListView(_items);
get size => _items.length;
void addItem(Item item) {
_items.add(item);
notifyListeners();
}
void toggleItem(Item item) {
item.toggle();
notifyListeners();
}
void removeItem(Item item) {
_items.remove(item);
notifyListeners();
}
}
Dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'model/item_data.dart';
import 'home.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => ItemData(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Provider Demo',
theme: ThemeData(
primarySwatch: Colors.green,
),
home: Home(),
),
);
}
}
Dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'model/item_data.dart';
class ItemList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer(builder: (context, data, child) {
return ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: data.size,
itemBuilder: (context, index) {
final item = data.items[index];
return GestureDetector(
onLongPress: () => data.removeItem(item),
child: Container(
padding: EdgeInsets.symmetric(vertical: 5),
child: ListTile(
leading: CircleAvatar(
backgroundColor: Colors.blueGrey,
child: Text(item.item[0]),
),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
item.item,
style: TextStyle(
decoration: item.completed
? TextDecoration.lineThrough
: null,
fontSize: 16,
fontWeight: FontWeight.bold),
),
Checkbox(
value: item.completed,
onChanged: (c) => data.toggleItem(item),
),
],
),
),
),
);
},
);
});
}
}
item_data。 dart包含一个列表,该列表将保存上面定义的 Item 类的数据。有一些方法可以执行添加、切换和从列表中删除项目等任务。
Dart
import 'dart:collection';
import 'package:flutter/foundation.dart';
import '../model/item.dart';
class ItemData with ChangeNotifier {
List- _items = [];
UnmodifiableListView
- get items => UnmodifiableListView(_items);
get size => _items.length;
void addItem(Item item) {
_items.add(item);
notifyListeners();
}
void toggleItem(Item item) {
item.toggle();
notifyListeners();
}
void removeItem(Item item) {
_items.remove(item);
notifyListeners();
}
}
现在模型已定义,我们将清理主要。dart
Dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'model/item_data.dart';
import 'home.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => ItemData(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Provider Demo',
theme: ThemeData(
primarySwatch: Colors.green,
),
home: Home(),
),
);
}
}
主要的。 dart有一个ChangeNotifierProvider ,它充当材质应用程序的父级。由于我们的应用程序很小,我们只在顶部定义了提供者。如果您的应用程序非常大,您可以将提供程序放在需要数据的小部件的顶部,而不是顶部。
item_list。 dart为来自列表的数据创建一个 ListView 构建器。它使用消费者来获取数据。
Dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'model/item_data.dart';
class ItemList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer(builder: (context, data, child) {
return ListView.builder(
scrollDirection: Axis.vertical,
shrinkWrap: true,
itemCount: data.size,
itemBuilder: (context, index) {
final item = data.items[index];
return GestureDetector(
onLongPress: () => data.removeItem(item),
child: Container(
padding: EdgeInsets.symmetric(vertical: 5),
child: ListTile(
leading: CircleAvatar(
backgroundColor: Colors.blueGrey,
child: Text(item.item[0]),
),
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
item.item,
style: TextStyle(
decoration: item.completed
? TextDecoration.lineThrough
: null,
fontSize: 16,
fontWeight: FontWeight.bold),
),
Checkbox(
value: item.completed,
onChanged: (c) => data.toggleItem(item),
),
],
),
),
),
);
},
);
});
}
}
最后,我们将为家庭编写代码。 dart文件,其中包含要显示在屏幕上的数据。它还包含一个 TextField 和一个用于将数据添加到列表的按钮。
输出:
除了提供者之外,还有其他状态管理可用,例如 –
- StatefulWidget :这些是材料包中提供的小部件。这些小部件具有内部状态,如果输入更改或小部件的状态更改,则可以重新构建该状态。
- InheritedWidget :这些是简单的小部件,其中包含要由其子代或后代使用的数据。这些提供了一种简单的机制来将数据移动到小部件树中远低于其下方的子项。有一个与之关联的元素会在元素更新时更改数据。 provider 包基本上是 InheritedWidgets 的包装器。
- ScopedModel :这个库取自 Fuchsia 代码库,它提供了一种将数据从父级传递给子级的方法。当模型改变时,子代被重建。我们的类可以扩展Model类来创建我们自己的模型。 ScopedModel Widget 包裹在其数据需要向下发送到小部件树的小部件周围。 ScopedModelDescendant Widget 用于监听发生在模型上的更改并重建子模型。
- BLOC:乙usiness螺GICÇomponent。这种技术允许我们将数据作为事件流来处理。它介于 UI 和处理应用程序逻辑的数据之间。 BLoC 的主要组件是Sink和Stream 。 StreamController 处理这些组件。接收器用于添加数据/事件,流用于监听它们。