无法使用 Provider.of(上下文) 调用 class 方法

Not able to call class method using Provider.of(context)

我正在学习使用此代码使用状态管理和提供程序包。

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<Data>(
      create: (context) => Data(),
      child: MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: MyText(),
          ),
          body: Level1(),
        ),
      ),
    );
  }
}

class Level1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Level2(),
    );
  }
}

class Level2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        MyTextField(),
        Level3(),
      ],
    );
  }
}

class Level3 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text(Provider.of<Data>(context).data);
  }
}

class MyText extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text(Provider.of<Data>(context).data);
  }
}

class MyTextField extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return TextField(
      onChanged: (newText) {
        print("onChanged Start");
        Provider.of<Data>(context).changeString(newText); //this line troubling me
        print("onChanged End");
      },
    );
  }
}

class Data extends ChangeNotifier {
  String data = "Some Data";

  void changeString(String newString) {
    print("changeString Start");
    print(newString + " changeString Text");
    data = newString;
    notifyListeners();
    print("changeString End");
  }
}

虽然 运行 应用程序、AppBar 文本 MyText() 和 Level 3 文本 Text() 工作正常。 就好像我在代码中更改了 data 的值,然后热重启 data 中更新的更改也反映在应用程序中。

我还创建了 MyTextFiled(),如果发生任何更改,它应该在 data 中更新,但是 changeString() 方法没有被第 64 行的 Provider.of<Data>(context) 调用。

这是我在文本字段中键入 "Test" 时的控制台输出。

onChange Start
t
onChange Start
te
onChange Start
tes
onChange Start
test

预期为:

onChange Start
t
changeString Start
t changeString Text
changeString End
onChange End
(so on .....)

我正在使用 provider: ^4.1.2 并且在教程(我正在关注)中,他们使用 provider: ^3.0.0+1 因此,我在第 10 行将 builder 更改为 create,因为它显示错误。

我的 Flutter 版本:

Flutter 1.17.0 • channel stable • https://github.com/flutter/flutter.git
Framework • revision e6b34c2b5c (4 weeks ago) • 2020-05-02 11:39:18 -0700
Engine • revision 540786dd51
Tools • Dart 2.8.1

PS:当我在这个例子 Provider Example

的帮助下将 Provider.of<Data>(context).changeString(newText); 替换为 context.read<Data>().changeString(newText); 时,我的问题得到解决

但我无法理解为什么 Provider.of(context) 不起作用但 context.read() 起作用。 请赐教解释。

我很抱歉在这个神圣的社区提出了一个愚蠢的问题。 并感谢listening/reading 细心解决我的问题

像这样更改您的 TextField 的 onChanged 函数:

class MyTextField extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return TextField(
      onChanged: (newText) {
        print("onChanged Start");
        Provider.of<Data>(context,listen:false).changeString(newText); //notice , listen default value is true
        print("onChanged End");
      },
    );
  }
}

关于 context.read<Data>() 你是对的,但你应该知道 context.read<T>() 等同于 Provider.of<T>(context,listen:false)

documentation中所述=>

  • context.watch<T>()Provider.of<T>(context)Provider.of<T>(context,listen:true) 相同,因为 listen 默认为 true
  • context.read<T>() 等同于 Provider.of<T>(context,listen:false)