没有消费者的 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),
  );
},
)

我的代码有错误吗?

您可以在此处 Consumersource 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> 取决于侦听值(truefalse)触发新的 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),
            );
          }),
        ));
  }
}