没有消费者的 Flutter Provider.of<> 不会改变我的状态
Flutter Provider.of<> without a consumer don't change my state
我正在尝试进入提供者主题,但是调用函数只有在我将其放入消费者时才有效
@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),
),
));
}
如本例所示,我的状态未更新。但是,它已经适用于消费者。
floatingActionButton: Consumer<ClickerProvider>(
builder: (context, value, child) {
return FloatingActionButton(
onPressed: Provider.of<ClickerProvider>(context, listen: false)
.incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
);
},
)
我的代码有错误吗?
您可以在此处 Consumer
的 source code 中参考:
Obtains [Provider] from its ancestors and passes its value to [builder].
The [Consumer] widget doesn't do any fancy work. It just calls [Provider.of]
in a new widget, and delegates its build
implementation to [builder].
Provider.of<X>
取决于侦听值(true
或 false
)触发新的 State.build()
到小部件和 State.didChangeDependencies()
触发 StatefulWidget
.
Consumer<X>
始终更新 UI,因为它使用 Provider.of<T>(context)
,其中监听是 true
在这种情况下,由于您的 listen
设置为 false,但您将其放在 Consumer
中使其成为 true
。这就是 UI 将更新为 Consumer
的原因
您可以复制粘贴运行下面的两个完整代码
原因:找不到 ClickerProvider
方案一:将ClickerProvider
移动到上层如MyApp
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => ClickerProvider()),
],
child: MaterialApp(
解决方案 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),
);
完整代码 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),
));
}
}
完整代码 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),
);
}),
));
}
}
我正在尝试进入提供者主题,但是调用函数只有在我将其放入消费者时才有效
@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),
),
));
}
如本例所示,我的状态未更新。但是,它已经适用于消费者。
floatingActionButton: Consumer<ClickerProvider>(
builder: (context, value, child) {
return FloatingActionButton(
onPressed: Provider.of<ClickerProvider>(context, listen: false)
.incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
);
},
)
我的代码有错误吗?
您可以在此处 Consumer
的 source code 中参考:
Obtains [Provider] from its ancestors and passes its value to [builder].
The [Consumer] widget doesn't do any fancy work. It just calls [Provider.of] in a new widget, and delegates its
build
implementation to [builder].
Provider.of<X>
取决于侦听值(true
或 false
)触发新的 State.build()
到小部件和 State.didChangeDependencies()
触发 StatefulWidget
.
Consumer<X>
始终更新 UI,因为它使用 Provider.of<T>(context)
,其中监听是 true
在这种情况下,由于您的 listen
设置为 false,但您将其放在 Consumer
中使其成为 true
。这就是 UI 将更新为 Consumer
您可以复制粘贴运行下面的两个完整代码
原因:找不到 ClickerProvider
方案一:将ClickerProvider
移动到上层如MyApp
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => ClickerProvider()),
],
child: MaterialApp(
解决方案 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),
);
完整代码 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),
));
}
}
完整代码 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),
);
}),
));
}
}