我正在学习使用此代码使用状态管理和提供程序包。
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<Data>(
create: (context) => Data(),
child: MaterialApp(
home: Scaffold(
appBar: AppBar(
title: MyText(),
),
body: Level1(),
),
),
);
}
}
class Level1 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: Level2(),
);
}
}
class Level2 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
MyTextField(),
Level3(),
],
);
}
}
class Level3 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text(Provider.of<Data>(context).data);
}
}
class MyText extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text(Provider.of<Data>(context).data);
}
}
class MyTextField extends StatelessWidget {
@override
Widget build(BuildContext context) {
return TextField(
onChanged: (newText) {
print("onChanged Start");
Provider.of<Data>(context).changeString(newText); //this line troubling me
print("onChanged End");
},
);
}
}
class Data extends ChangeNotifier {
String data = "Some Data";
void changeString(String newString) {
print("changeString Start");
print(newString + " changeString Text");
data = newString;
notifyListeners();
print("changeString End");
}
}
运行应用时,应用栏文本MyText()
和级别 3 文本Text()
工作正常。 好像我更改了代码中data
的值并热重启了data
中更新的更改,这些更改也反映在应用程序中。
我还创建了MyTextFiled()
发生任何更改的地方,它应该在data
中更新,但第 64 行的Provider.of<Data>(context)
没有调用changeString()
方法。
这是我在文本字段中键入"测试"时的控制台输出。
onChange Start
t
onChange Start
te
onChange Start
tes
onChange Start
test
预期是:
onChange Start
t
changeString Start
t changeString Text
changeString End
onChange End
(so on .....)
我正在使用provider: ^4.1.2
,在教程(我正在遵循(中,他们使用provider: ^3.0.0+1
因此,我将第 10 行中的builder
更改为create
,因为它显示错误。
我的颤振版本:
Flutter 1.17.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision e6b34c2b5c (4 weeks ago) • 2020-05-02 11:39:18 -0700
Engine • revision 540786dd51
Tools • Dart 2.8.1
PS:当我在此示例的帮助下将Provider.of<Data>(context).changeString(newText);
替换为context.read<Data>().changeString(newText);
时,我的问题得到了解决 提供程序示例
但是我无法理解为什么 Provider.of(context( 不起作用,但 context.read(( 工作。 请用解释来启发我。
我很抱歉在这个神圣的社区上提出了一个愚蠢的问题。 并感谢您仔细聆听/阅读我的问题。
像这样更改TextField的onChanged函数:
class MyTextField extends StatelessWidget {
@override
Widget build(BuildContext context) {
return TextField(
onChanged: (newText) {
print("onChanged Start");
Provider.of<Data>(context,listen:false).changeString(newText); //notice , listen default value is true
print("onChanged End");
},
);
}
}
你对context.read<Data>()
的看法是对的,但你应该知道context.read<T>()
等同于Provider.of<T>(context,listen:false)
如文档中所述=>
context.watch<T>()
与Provider.of<T>(context)
或Provider.of<T>(context,listen:true)
相同,因为默认情况下侦听为 true
。context.read<T>()
与Provider.of<T>(context,listen:false)
相同