[英]Flutter Provider.of<> without a consumer don't change my state
I am trying to get into the provider topic, however calling a function only works if I put it into a consumer我正在尝试进入提供者主题,但是调用 function 仅在我将其放入消费者时才有效
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => ClickerProvider()),
],
child: Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Text("some text"),
),
floatingActionButton: FloatingActionButton(
onPressed: () => Provider.of<ClickerProvider>(context, listen: false)
.incrementCounter(),
tooltip: 'Increment',
child: Icon(Icons.add),
),
));
}
As in this example, my state is not updated.如本例所示,我的 state 未更新。 However, it already works with a consumer.
但是,它已经与消费者合作。
floatingActionButton: Consumer<ClickerProvider>(
builder: (context, value, child) {
return FloatingActionButton(
onPressed: Provider.of<ClickerProvider>(context, listen: false)
.incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
);
},
)
Is there an error in my code?我的代码有错误吗?
As you can refer in the source code of Consumer
here:您可以在此处参考
Consumer
的源代码:
Obtains [Provider] from its ancestors and passes its value to [builder].
从其祖先获取 [Provider] 并将其值传递给 [builder]。
The [Consumer] widget doesn't do any fancy work.
[Consumer] 小部件不做任何花哨的工作。 It just calls [Provider.of] in a new widget, and delegates its
build
implementation to [builder].它只是在一个新的小部件中调用 [Provider.of],并将其
build
实现委托给 [builder]。
Provider.of<X>
depends on value of listen ( true
or false
) to trigger new State.build()
to widgets and State.didChangeDependencies()
for StatefulWidget
. Provider.of<X>
取决于 listen 的值( true
或false
)来触发新的State.build()
到小部件和State.didChangeDependencies()
到StatefulWidget
。
Consumer<X>
always update UI, as it uses Provider.of<T>(context)
, where listen is true
Consumer<X>
总是更新 UI,因为它使用Provider.of<T>(context)
,其中 listen 为true
In this case, since your listen
is set as false, but you're putting it in the Consumer
which make it true
.在这种情况下,由于您的
listen
设置为 false ,但您将其放入Consumer
使其变为true
。 That's why the UI will update with Consumer
这就是 UI 将使用
Consumer
更新的原因
You can copy paste run two full code below您可以在下面复制粘贴运行两个完整代码
Reason: Can not find ClickerProvider
原因:找不到
ClickerProvider
Solution 1: Move ClickerProvider
to upper level such as MyApp
解决方案一:将
ClickerProvider
移到MyApp
等上层
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => ClickerProvider()),
],
child: MaterialApp(
Solution 2: Use Builder
解决方案 2:使用
Builder
body: Center(child: Builder(builder: (BuildContext context) {
return Text(context.watch<ClickerProvider>().getCounter.toString());
})),
floatingActionButton: Builder(builder: (BuildContext context) {
return FloatingActionButton(
onPressed: () =>
Provider.of<ClickerProvider>(context, listen: false)
.incrementCounter(),
tooltip: 'Increment',
child: Icon(Icons.add),
);
full code 1完整代码 1
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ClickerProvider extends ChangeNotifier {
int _count = 0;
int get getCounter {
return _count;
}
void incrementCounter() {
_count += 1;
notifyListeners();
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => ClickerProvider()),
],
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
));
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Text(context.watch<ClickerProvider>().getCounter.toString()),
),
floatingActionButton: FloatingActionButton(
onPressed: () => Provider.of<ClickerProvider>(context, listen: false)
.incrementCounter(),
tooltip: 'Increment',
child: Icon(Icons.add),
));
}
}
full code 2完整代码 2
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class ClickerProvider extends ChangeNotifier {
int _count = 0;
int get getCounter {
return _count;
}
void incrementCounter() {
_count += 1;
notifyListeners();
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => ClickerProvider()),
],
child: Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(child: Builder(builder: (BuildContext context) {
return Text(context.watch<ClickerProvider>().getCounter.toString());
})),
floatingActionButton: Builder(builder: (BuildContext context) {
return FloatingActionButton(
onPressed: () =>
Provider.of<ClickerProvider>(context, listen: false)
.incrementCounter(),
tooltip: 'Increment',
child: Icon(Icons.add),
);
}),
));
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.