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.
的导入
我收到 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.
的导入