【问题标题】:Flutter Provider.of<> without a consumer don't change my stateFlutter Provider.of<> 没有消费者不要改变我的状态
【发布时间】:2021-06-16 11:20:15
【问题描述】:

我正在尝试进入提供者主题,但是只有将函数放入消费者中才能调用函数

@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),
  );
},
)

我的代码有错误吗?

【问题讨论】:

    标签: flutter dart provider


    【解决方案1】:

    您可以在下面复制粘贴运行两个完整代码
    原因:找不到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),
                );
              }),
            ));
      }
    }
    

    【讨论】:

      【解决方案2】:

      您可以在此处参考Consumersource code

      从其祖先获取 [Provider] 并将其值传递给 [builder]。

      [Consumer] 小部件不做任何花哨的工作。它只是调用 [Provider.of] 在一个新的小部件中,并将其 build 实现委托给 [builder]。

      Provider.of&lt;X&gt; 依赖于监听值(truefalse)触发新的State.build() 到小部件和State.didChangeDependencies() 用于StatefulWidget

      Consumer&lt;X&gt; 总是更新 UI,因为它使用 Provider.of&lt;T&gt;(context),其中 listen 是 true

      在这种情况下,由于您的 listen 设置为 false,但您将其放入 Consumer 中,从而使其成为 true。这就是为什么 UI 会更新为Consumer

      【讨论】:

        猜你喜欢
        • 2021-11-06
        • 1970-01-01
        • 2020-02-06
        • 2020-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-12
        • 1970-01-01
        相关资源
        最近更新 更多