ProviderNotFoundException (Error: Could not find the correct Provider<LayoutData> above this SchedulingPage Widget using layoutBuilder

ProviderNotFoundException (Error: Could not find the correct Provider<LayoutData> above this SchedulingPage Widget using layoutBuilder

我收到 providerNotFoundException,我怀疑下面的代码中存在上下文不匹配,但我很难看到它。据我了解,当在同一构建方法中执行 .of 方法时,BuilderContext 会出现问题,但在这种情况下我没有看到这种情况发生。某些 Provider.of 方法工作正常,如以下代码中所注释,但一旦调用 SchedulingPage,Provider.of 方法就不再起作用。

这里有什么问题?

编辑:我更新为使用下面的完整代码: 这是完整的错误:ProviderNotFoundException(错误:无法在此 LoginForm Widget

上方找到正确的提供者
void main() {
  runApp(
    Home(),
  );
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        // ChangeNotifierProvider(create: (context) => CalendarData()),
        ChangeNotifierProvider(create: (context) => LayoutData()),
      ],
      child: MyApp(),
    );
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SafeArea(
        child: LayoutBuilder(
            builder: (BuildContext context, BoxConstraints constraints) {
          print("constraints: $constraints");
          Size mediaSize = MediaQuery.of(context).size;
          double safeAreaSize = mediaSize.height - constraints.maxHeight;
          Provider.of<LayoutData>(context).safeAreaDiff = safeAreaSize;
          Provider.of<LayoutData>(context).safeArea = constraints;
          Provider.of<LayoutData>(context).mediaArea = mediaSize;
          var test = Provider.of<LayoutData>(context).mediaArea.width;
          print(test);  // this works

          return Scaffold(body: LoginScreen());
        }),
      ),
    );
  }
}

    class LoginScreen extends StatelessWidget {
      const LoginScreen({Key key}) : super(key: key);

      @override
      Widget build(BuildContext context) {
        double test = Provider.of<LayoutData>(context).mediaArea.width;
        print("test: $test");  // this works
        return LoginForm();
      }
    }

    class LoginForm extends StatefulWidget {
      LoginForm({Key key}) : super(key: key);

      @override
      _LoginFormState createState() => _LoginFormState();
    }

    class _LoginFormState extends State<LoginForm> {
      @override
      Widget build(BuildContext context) {
        double width = Provider.of<LayoutData>(context).mediaArea.width; // The code fails here
        print('width: $width');
        return Text("this is where it fails ^^^^^^^^");
      }
    }

    class LayoutData with ChangeNotifier {
      double safeAreaDiff = 0.0;
      BoxConstraints safeArea;
      Size mediaArea;

      LayoutData() {
        initializeApp();
      }

      void initializeApp() {
        print("layout initialized");
      }
    }

您是否尝试过将 MultiProvider() 置于 MaterialApp() 之上?

您无法在您创建的 class 中访问提供程序。那必须是父部件。

void main() {
  runApp(Home());
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (context) => CalendarData()),
        ChangeNotifierProvider(create: (context) => LayoutData()),
      ],
      child: MyApp(),
    );
  }
}


class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: SafeArea(
        child: LayoutBuilder(
            builder: (BuildContext context, BoxConstraints constraints) {
          print("constraints: $constraints");
          Size mediaSize = MediaQuery.of(context).size;
          double safeAreaSize =
              mediaSize.height - constraints.maxHeight; // works
          Provider.of<LayoutData>(context).safeAreaDiff =
              safeAreaSize; // works
          Provider.of<LayoutData>(context).safeArea = constraints; // works
          Provider.of<LayoutData>(context).mediaArea = mediaSize; // works
          Provider.of<CalendarData>(context).working = "beer"; // works
          print(Provider.of<CalendarData>(context).working); // works

          return Scaffold(body: SchedulingPage());
        }),
      ),
    );
  }
}

输出:

Performing hot restart...                                               
Restarted application in 1,181ms.
I/flutter (25187): constraints: BoxConstraints(w=411.4, h=659.4)
I/flutter (25187): layout initialized
I/flutter (25187): 411.42857142857144
I/flutter (25187): test: 411.42857142857144
I/flutter (25187): width: 411.42857142857144

我发布这篇文章是为了防止有人遇到与我相同的问题。事实证明,所选解决方案并未解决该问题。所写的代码应该有效。但是,在这种情况下,很难找到解决方案。事实证明,导入本身是不正确的。提供程序数据有两次导入 Class,如下所示:

import 'package:myProject/providers/CalendarData.dart'; 

import 'package:gcfdlayout2/Providers/CalendarData.dart';

这种歧义混淆了 IDE,我相信,虽然它在构建时没有给我任何错误,但它在 运行 时出现了,但是 "could not find Provider"让我假设它无法在树中找到提供者,而不是在代码本身中。

我最终找到的方法是使用 运行 代码的其他方法。最初,我只使用 Visual Studio 代码,但我从未收到任何表明这是导入问题的错误。我更改为 Android Studio,它告诉我有两个 CalendarData class.

的导入