I want to navigate to the next screen after bloc listener checks the state, but in my UI, the bloc listener does not know that the state has changed. Therefore, the state is changed on<event>((state,emit)) after emitting to the next state.
Here is my code:
import 'package:bloc/bloc.dart';
import 'package:bloctest/bloc/events.dart';
import 'package:bloctest/bloc/states.dart';
class AppBloc extends Bloc<AppEvent,AppState>{
AppBloc(AppState initialState):super(initialState){
on<AppStartEvent>((event, emit) {
emit(AppInitState());
});
on<NavigatorButtonPressed>((event, emit) {
emit(NavigationSucceedState());
print('navigation succeed');
});
}
}
import 'package:bloctest/bloc/bloc.dart';
import 'package:bloctest/bloc/states.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'bloc/events.dart';
import 'main2.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool isNavigationSuccess=false;
AppBloc appBloc=AppBloc(AppInitState());
@override
Widget build(BuildContext context) {
return MaterialApp(
home: BlocProvider<AppBloc>(
create: (context)=>AppBloc(AppInitState())..add(AppStartEvent()),
child: Scaffold(
body: BlocListener<AppBloc, AppState>(
listener: (context , state)async{
if(state is NavigationSucceedState){
await Future.delayed(const Duration(seconds: 1));
Navigator.push(context, MaterialPageRoute(builder: (context)=>MyApp2()));
}
},
child:BlocBuilder<AppBloc,AppState>(
builder:(context,state){
context.read<AppBloc>().add(AppStartEvent());
return state is AppStartingState?const Center(child: CircularProgressIndicator(),):
Scaffold(
body: SafeArea(child: Center(
child: ElevatedButton(
onPressed: () {
appBloc.add(NavigatorButtonPressed());
},
child: const Text('tap to go to next page')),
)),
);
}
),
),
),
)
);
}
}
Try this:
class AppBloc extends Bloc<AppEvent,AppState>{
AppBloc() : super(AppStartingState()){
on<NavigatorButtonPressed>((event, emit) {
emit(NavigationSucceedState());
print('navigation succeed');
});
}
}
In UI:
class _MyAppState extends State<MyApp> {
bool isNavigationSuccess = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: BlocProvider<AppBloc>(
create: (context) => AppBloc(),
child: BlocListener<AppBloc, AppState>(
listener: (context, state) {
if (state is NavigationSucceedState) {
Future.delayed(const Duration(seconds: 1), () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => MyApp2()));
});
}
},
child: BlocBuilder<AppBloc, AppState>(
builder: (context, state) => state is AppStartingState
? const Center(child: CircularProgressIndicator())
: Scaffold(
body: SafeArea(
child: Center(
child: ElevatedButton(
onPressed: () {
context.read<AppBloc>.add(
NavigatorButtonPressed(),
);
},
child: const Text('tap to go to next page')),
),
),
),
),
),
),
);
}
}