繁体   English   中英

Flutter Provider.of<> 没有消费者不要更改我的 state

[英]Flutter Provider.of<> without a consumer don't change my state

我正在尝试进入提供者主题,但是调用 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),
      ),
    ));
}

如本例所示,我的 state 未更新。 但是,它已经与消费者合作。

floatingActionButton: Consumer<ClickerProvider>(
builder: (context, value, child) {
  return FloatingActionButton(
    onPressed: Provider.of<ClickerProvider>(context, listen: false)
        .incrementCounter,
    tooltip: 'Increment',
    child: Icon(Icons.add),
  );
},
)

我的代码有错误吗?

您可以在此处参考Consumer源代码

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

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

Provider.of<X>取决于 listen 的值( truefalse )来触发新的State.build()到小部件和State.didChangeDependencies()StatefulWidget

Consumer<X>总是更新 UI,因为它使用Provider.of<T>(context) ,其中 listen 为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),
            );
          }),
        ));
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM