Ave*_*der 3 dart flutter flutter-provider
所以我在我的小部件树中设置了这个 ChangeNotifierProvider,因为我看到很多子小部件来聆听它的价值。
我目前正在做的是,每当我要在我的子小部件上重用某些值/函数时,我都会通过构造函数将Provider.of(context)对象从父小部件传递给它的子小部件。例如,每次我为我的孩子小部件创建一个Provider.of(context)对象时,它似乎没有继承我在父 Provider 上的更新值,而是这个具有我的默认值 null/0/'empty'像它这样的只是被创造出来的。这导致我将初始Provider.of(context)对象传递给每个将使用 ChangeNotifier 更新值和函数的子级。
这个设置对我有用,但是,当我的小部件树开始变得复杂时,我不断地通过每个小部件向下传递值,甚至将值传递给一些甚至根本不使用它的人,只是为了让它的孩子听主提供者。
我认为我现在可能正在做的是提供者架构的反模式,我希望你们能以更优化和更有效的方式帮助我做到这一点。
非常感谢!
PS 文档中的一些内容我还没有完全掌握。
编辑以下以包含示例代码和可视化:
provider_type.dart
class ProviderType extends ChangeNotifier{
String valueA = '';
String valueB = '';
}
Run Code Online (Sandbox Code Playgroud)
家.dart
import ..provider_type.dart
...
Widget build(BuildContext context){
return ChangeNotifierProvider<ProviderType>(
create: (context) => ProviderType(),
child: ScreenColumn();
);
}
...
Run Code Online (Sandbox Code Playgroud)
screen_column.dart
import ..screen_a.dart
import ..screen_b.dart
class ScreenColumn extends StatelessWidget{
Widget build(BuildContext context){
var providerType = Provider.of<ProviderType>(context);
return Column(
children: <Widget>[
ScreenA(providerType: providerType),
ScreenB(providerType: providerType),
],
);
}
}
Run Code Online (Sandbox Code Playgroud)
screen_a.dart
class ScreenA extends StatelessWidget{
final ProviderType providerType;
ScreenA({this.providerType});
Widget build(BuildContext context){
return Text(
'${providerType.valueA}'
);
}
}
Run Code Online (Sandbox Code Playgroud)
screen_b.dart
import ..screen_c.dart
class ScreenB extends StatelessWidget{
final ProviderType providerType;
ScreenB({this.providerType});
Widget build(BuildContext context){
return ScreenC(providerType: providerType);
}
}
Run Code Online (Sandbox Code Playgroud)
screen_c.dart
class ScreenC extends StatelessWidget{
final ProviderType providerType;
ScreenB({this.providerType});
Widget build(BuildContext context){
return Column(
children: <Widget>[
Text(
'${providerType.valueA}'
)
Text(
'${providerType.valueB}'
)
Text(
'${providerType.valueC}'
)
]
);
}
}
Run Code Online (Sandbox Code Playgroud)
可视化
所以我目前正在做的是将对象providerType从 ScreenColumn 传递到屏幕 A、B 和 C,以便它们每个都具有相同的“值来源”。因为当我尝试创建不同的 Provider.of 对象并使用它们时,当我进行一些计算时,它们不会共享相同的更新值。
有什么我可以做的事情来提高效率还是有更好的方法我需要做?
对于那些可能想知道或正在寻找同一问题答案的人,请查看我下面的示例代码,该代码显示了如何在小部件树中的任何点重用/共享您的 Provider 值和函数,只要它们在您的父项下提供者。
是的,您实际上可以在树中的任何位置创建 Provider.of 对象,而无需传递您创建的初始 Provider.of 对象。
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ProviderType extends ChangeNotifier {
String value = DateTime.now().toString();
changeValue() {
value = DateTime.now().toString();
notifyListeners();
}
}
void main() => runApp(AppIndex());
class AppIndex extends StatelessWidget {
const AppIndex({
Key key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<ProviderType>(
create: (context) => ProviderType(),
child: MaterialApp(
home: Home(),
),
);
}
}
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
var providerType = Provider.of<ProviderType>(context);
return Scaffold(
appBar: AppBar(
title: Text('Sample App'),
),
body: ScreenColumn(),
floatingActionButton: FloatingActionButton.extended(
onPressed: () => providerType.changeValue(),
label: Text('ChangeValue'),
),
);
}
}
class ScreenColumn extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
ScreenA(),
ScreenB(),
ScreenC(),
ScreenC(),
],
));
}
}
class ScreenA extends StatelessWidget {
@override
Widget build(BuildContext context) {
var providerType = Provider.of<ProviderType>(context);
return Card(
color: Colors.red,
elevation: 8.0,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Text(providerType.value),
),
);
}
}
class ScreenB extends StatelessWidget {
@override
Widget build(BuildContext context) {
var providerType = Provider.of<ProviderType>(context);
return Card(
color: Colors.blue,
elevation: 8.0,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(providerType.value),
ScreenC(),
ScreenC(),
],
),
),
);
}
}
class ScreenC extends StatelessWidget {
@override
Widget build(BuildContext context) {
// var providerType = Provider.of<ProviderType>(context);
return Card(
color: Colors.green,
elevation: 8.0,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text('This is Screen B with no Provider.of Object'),
ScreenD(),
ScreenD(),
ScreenD(),
],
),
),
);
}
}
class ScreenD extends StatelessWidget {
@override
Widget build(BuildContext context) {
var providerType = Provider.of<ProviderType>(context);
return Card(
color: Colors.yellow,
elevation: 8.0,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(
'This is Screen D. A Provider.of object was created here without inheriting the Parent\'s Provider.of object.'),
Text(providerType.value),
],
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3637 次 |
| 最近记录: |