'Error: Could not find the correct Provider<MainBloc> above this HomePageState Widget
I have a homepage with MultiBlocProvider , now its working well without the splash screen but when I try to add a splash screen before the home page it gives me the below error
Error: Could not find the correct Provider above this HomePageState Widget
this is my " main.dart "
void main() async {
await initHiveForFlutter();
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
await Hive.openBox('user');
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ValueListenableBuilder(
valueListenable: Hive.box('user').listenable(),
builder: (context, Box box, widget) {
return MyGraphqlProvider(
uri: "${serverUrl}graphql",
subscriptionUri: "${wsUrl}graphql",
jwt: box.get('jwt').toString(),
child: MaterialApp(
debugShowCheckedModeBanner: false,
onGenerateTitle: (BuildContext context) => S.of(context).app_name,
title: 'Amigo',
localizationsDelegates: const [
S.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: S.delegate.supportedLocales,
routes: {
'addresses': (context) => const AddressListView(),
'announcements': (context) => const AnnouncementsListView(),
'history': (context) => const TripHistoryListView(),
'wallet': (context) => const WalletView(),
'chat': (context) => const ChatView(),
//'coupons': (context) => const CouponsListView(),
'profile': (context) => ProfileView()
},
theme: CustomTheme.theme1,
home: MultiBlocProvider(
providers: [
BlocProvider(create: (context) => MainBloc()),
BlocProvider(create: (context) => LocationsCubit())
],
child: const MyHomePage(),
),
),
);
},
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
//State<StatefulWidget> createState() => HomePageState();
SplashScreenState createState() => SplashScreenState();
}
class SplashScreenState extends State<MyHomePage> {
@override
void initState() {
super.initState();
Timer(Duration(seconds: 5),
()=>Navigator.pushReplacement(context,
MaterialPageRoute(builder:
(context) => HomePageState()
)
)
);
}
@override
Widget build(BuildContext context) {
return Container(
color: Colors.yellow,
child:FlutterLogo(size:MediaQuery.of(context).size.height)
);
}
}
class HomePageState extends StatelessWidget {
late GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
final mainBloc = context.read<MainBloc>();
return Scaffold(
key: scaffoldKey,
drawer: Drawer(
child: ValueListenableBuilder(
valueListenable: Hive.box('user').listenable(),
builder: (context, Box box, widget) {
if (box.get('jwt') == null) {
return const DrawerLoggedOut();
} else {
return const DrawerLoggedIn();
}
}),
),
body: Query(
options: QueryOptions(
document: GET_CURRENT_ORDER_QUERY_DOCUMENT,
fetchPolicy: FetchPolicy.noCache),
builder: (QueryResult result,
{Refetch? refetch, FetchMore? fetchMore}) {
if (result.isLoading) {
return const Center(child: CircularProgressIndicator.adaptive());
}
if (result.data != null) {
final _order = GetCurrentOrder$Query.fromJson(result.data!)
.currentOrderWithLocation;
mainBloc.add(OrderUpdated(
order: _order.order, driverLocation: _order.driverLocation));
}
return BlocBuilder<MainBloc, MainBlocState>(
builder: (context, state) {
if (state is OrderLooking) {
return const LookingScreenView();
}
return Stack(children: [
if (mapProvider == MapProvider.openStreetMap ||
mapProvider == MapProvider.mapBox)
const OpenStreetMapProvider(),
if (mapProvider == MapProvider.googleMap)
const GoogleMapProvider(),
if (state is SelectingPoints && state.points.isEmpty)
FloatingActionButton(
heroTag: 'menuFab',
onPressed: () => scaffoldKey.currentState?.openDrawer(),
backgroundColor: Colors.white,
child: const Icon(
Icons.menu,
color: Colors.black,
),
).safeArea(minimum: const EdgeInsets.all(16)).objectTopLeft(),
if (state is SelectingPoints && state.points.isNotEmpty)
FloatingActionButton(
heroTag: 'removeFab',
onPressed: () => mainBloc.add(DropLastPoint()),
backgroundColor: Colors.white,
child: const Icon(
Icons.arrow_back,
color: Colors.black,
),
).safeArea(minimum: const EdgeInsets.all(16)),
Container(
constraints: const BoxConstraints(maxWidth: 500),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (state is OrderInProgress ||
state is OrderInvoice ||
state is OrderReview)
Subscription(
options: SubscriptionOptions(
document: UPDATED_ORDER_SUBSCRIPTION_DOCUMENT,
fetchPolicy: FetchPolicy.noCache),
builder: (QueryResult result) {
if (result.data != null) {
final _order =
GetCurrentOrder$Query$CurrentOrder$Order
.fromJson(
result.data!['orderUpdated']);
if ((state is OrderInProgress &&
state.currentOrder.status !=
_order.status) ||
(state is OrderInvoice &&
state.currentOrder.status !=
_order.status) ||
(state is OrderReview &&
state.currentOrder.status !=
_order.status)) {
WidgetsBinding.instance
?.addPostFrameCallback((_) {
mainBloc.add(OrderUpdated(order: _order));
});
}
}
if (state is OrderInProgress) {
return DriverInfoCardView(
order: state.currentOrder);
}
if (state is OrderInvoice) {
return const OrderInvoiceCardView();
}
if (state is OrderReview) {
return OrderReviewCardView();
}
return const Text("Unacceptable state");
}),
if (state is OrderPreview)
const ServiceSelectionCardView(),
if (state is SelectingPoints) PointSelectionView()
]),
).centered().safeArea(minimum: const EdgeInsets.all(8))
]);
});
}),
);
}
}
please anyone can help me with this ?
Solution 1:[1]
You could use a single BlocProvider to wrap directly around MyHomePage.
So your MultiBlocProvider would no longer have your MainBloc and use SplashScreen as its child.
MultiBlocProvider(
providers: [
BlocProvider(
create: (context) => LocationsCubit(),
),
],
child: SplashScreen(),
),
Then just a regular SplashScreen
class SplashScreen extends StatefulWidget {
const SplashScreen({Key? key}) : super(key: key);
@override
State<SplashScreen> createState() => _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> {
@override
void initState() {
super.initState();
Timer(
Duration(seconds: 2),
() => Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => BlocProvider( // now this is providing context
create: (context) => MainBloc(),
child: MyHomePage(),
)),
),
);
}
...rest of build method
That should do it.
Also, the _State portion of a StatefulWidget is private (marked with a preceding _) for a reason. So FYI what you're trying to do here is not something that is meant to be done, especially attempting to access the _State portion of a different widget.
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
//State<StatefulWidget> createState() => HomePageState();
SplashScreenState createState() => SplashScreenState();
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Loren.A |
