我创建了一个虚拟预算应用程序,其中包含 2 个列表视图;收入和支出,其中将根据用户保存的内容填充相应的列表(例如,单击按钮将显示一个表单,用户可以在其中选择要输入的收入或支出以及保存后的金额,相关列表将被填充。)
我现在已经观看了有关如何在应用程序中创建“入职”旅程的视频教程。
我现在面临的问题是,当用户通过单击表单上的
save
按钮来保存收入/费用时,我收到以下错误:
The following ProviderNotFoundException was thrown while handling a gesture:
Error: Could not find the correct Provider<FinanceBloc> above this Builder Widget
This happens because you used a `BuildContext` that does not include the provider
of your choice. There are a few common scenarios:
- You added a new provider in your `main.dart` and performed a hot-reload.
To fix, perform a hot-restart.
- The provider you are trying to read is in a different route.
Providers are "scoped". So if you insert of provider inside a route, then
other routes will not be able to access that provider.
- You used a `BuildContext` that is an ancestor of the provider you are trying to read.
Make sure that Builder is under your MultiProvider/Provider<FinanceBloc>.
This usually happens when you are creating a provider and trying to read it immediately.
有几点需要注意:
- 要显示入门屏幕,我必须更改应用程序的运行方式,以前是:
void main() {
Bloc.observer = const GlobalApplicationObserver();
runApp(MyApp());
}
但现在是:
void main() {
Bloc.observer = const GlobalApplicationObserver();
runApp(MaterialApp(home: OnboardingPageWidget()));
}
MyApp()
本质上是一个目前有1个选项卡的
DefaultTabController
,选项卡显示的页面是有2个列表的屏幕。在此类的构建方法中返回
BlocProvider
,在构建方法中是选项卡控制器页面/这是我的入职课程:
import 'package:budgetapplication/main.dart';
import 'package:budgetapplication/repository/expenditure_repository.dart';
import 'package:flutter/material.dart';
//This is a private class
class _OnboardingPageState extends State<OnboardingPageWidget> {
final PageController controller = PageController();
bool isLastPage = false;
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
padding: EdgeInsets.only(bottom: 80),
child: PageView(
controller: controller,
onPageChanged: (index) {
setState(() {
isLastPage = index == 1;
});
},
children: [
Container(
color: Colors.amber,
child: Center(
child: Text('Page 1'),
),
),
Container(
color: Colors.red,
child: Center(
child: Text('Page 2'),
),
)
],
),
),
bottomSheet: Container(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Row(
children: [
isLastPage
? TextButton(
child: Text('Finish!'),
onPressed: () async {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => MyApp()));
},
)
: TextButton(
child: Text('Next'),
onPressed: () {
controller.nextPage(
duration: Duration(milliseconds: 500),
curve: Curves.bounceInOut);
},
)
],
),
));
}
}
class OnboardingPageWidget extends StatefulWidget {
@override
State<OnboardingPageWidget> createState() => _OnboardingPageState();
}
我怀疑由于路由的原因,上下文正在丢失?不确定,但任何帮助将不胜感激!
在使用 BLoC 值之前,您需要像这样添加提供者:
void main() {
Bloc.observer = const GlobalApplicationObserver();
runApp(
BlocProvider(
create: (context) => FinanceBloc(), // Create your FinanceBloc
child: MyApp(), // Your main app widget
),
);
}
通过像这样添加提供程序,您可以在整个小部件树中使用此 BLoC。您可以稍后根据您的要求对其进行自定义,以获得更好的性能。确保在添加新的块提供程序后热重载但是简单来说,你必须先添加provider,然后才能使用它:
onPressed: () {
final financeBloc = BlocProvider.of<FinanceBloc>(context);
// Use your financeBloc here
},
让我知道您仍然遇到此错误