Hello, I have project where I need to build different parts of one screen according to 2 states here is what I did:
my Home screen:
`
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: BlocBuilder
builder: (BuildContext context, state) {
return SingleChildScrollView(
child: Container(
decoration: new BoxDecoration(color: Color(0xfffafafa)),
child: Column(
children: [
if (state is SliderLoaded) ...{
CarouselSlider(
items: state.response
.map
.toList(),
options: CarouselOptions(
scrollDirection: Axis.horizontal,
autoPlay: true,
height: MediaQuery.of(context).size.height * 0.29,
),
),
} else if (state is SliderLoading) ...{
Container(
height: 30,
width: 30,
child: CircularProgressIndicator(),
)
} else if (state is SliderLoadFailure)
Center(child: Text(state.error)),
BlocBuilder
builder: (context,state){
if(state is CategoryLoaded){
categoriesForHome=state.categoryResponse.categories.skip(5).take(2);
}
return Container(
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.only(
// top: MediaQuery.of(context).size.height * 0.00009,
left: MediaQuery.of(context).size.width * 0.04,
right: MediaQuery.of(context).size.width * 0.04,
),
child: Flex(
direction: Axis.horizontal,
children: [
// if(state is CategoryLoaded)
Expanded(
child: Stack(
children: <Widget>[
Opacity(
opacity: 0.15000000596046448,
child: Container(
height: 318.h,
),
),
Positioned.fill(
child: Container(
child: Image(
image: AssetImage(
'assets/images/top_cat2/topcat2.png'),
),
),
),
Positioned(
top: 175.0.h,
left: 56.0.w,
child: Column(
children: [
Text(categoriesForHome!=null?categoriesForHome.first.name: "兀胤賱丕賱鬲賰 丕賱噩丿賷丿丞 賱賱丿賵丕賲",
style: TextStyle(
fontFamily: 'HelveticaNeueLTArabic',
color: Color(0xffffffff),
fontSize: 14,
fontWeight: FontWeight.w700,
fontStyle: FontStyle.normal,
)),
SizedBox(
height: 8.0.h,
),
Container(
alignment: Alignment.center,
margin: EdgeInsets.only(left: 140.w),
width: 118.w,
height: 40.h,
decoration: new BoxDecoration(
color: Color(0xffffffff)),
child: new Text("鬲爻賵賯賶 丕賱兀賳",
style: TextStyle(
fontFamily: 'HelveticaNeueLTArabic',
color: Color(0xff000000),
fontSize: 15.ssp,
fontWeight: FontWeight.w700,
fontStyle: FontStyle.normal,
)),
)
],
))
],
),
),
}
),
],
),
),
);
}),
`
and here is my category bloc:
`class CategoryBloc extends Bloc
final categoryRepository=CategoryRepository();
@override
CategoryState get initialState => CategoryInitial();
@override
Stream
CategoryEvent event,
) async* {
if(event is GetCategories){
yield CategoryLoading();
final categoryResponse=await categoryRepository.categories();
yield CategoryLoaded(categoryResponse);
}
}
}`
and here is my home bloc:
`class HomeBloc extends Bloc
HomeRepository _homeRepository;
HomeBloc(){
_homeRepository=HomeRepository();
}
@override
HomeState get initialState => HomeInitial();
@override
Stream
HomeEvent event,
) async* {
print('hello from there!');
if(event is GetSlider){
yield SliderLoading();
try{
final response=await _homeRepository.getSlider();
print(response.toString());
yield SliderLoaded(response);
CategoryBloc().add(GetCategories());//after slider call the categories //first time I did this event dispatch from multibloc provi
//but didn't work any advice?
}catch(error){
print(error.toString());
yield SliderLoadFailure(error.toString());
CategoryBloc().add(GetCategories());//after slider call the categories
}
}
}
}
`
here is myApp:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: MultiBlocProvider(
providers: [
BlocProvider<HomeBloc>(
lazy: false,
create: (context) => HomeBloc()..add(GetSlider()),
),
BlocProvider<CategoryBloc>(
lazy: false,
create: (context) => CategoryBloc()//..add(GetCategories()), //here tried to fire 2 events together but gave no result?
),
], //IntroBloc()..add(GetDefaultLanguage()),//RegisterBloc() ,
child: HomeScreen(), //IntroScreen()//SignInScreen(),
),
);
}
}
Now the slider response is coming to the UI but the categories when yield doesn't exposed in the UI
I need solution for this please?
@felangel please have look this?
Hi @EngAddow 馃憢
Thanks for opening an issue!
If you need to react to two separate states in your UI you can nest BlocBuilders like:
@override
Widget build(BuildContext context) {
return BlocBuilder<BlocA, StateA>(
builder: (context, stateA) {
return BlocBuilder<BlocB, StateB>(
builder: (context, stateB) {
// do something here based on stateA and stateB
},
);
},
);
}
Another option is to refactor your two blocs into a single bloc if they are not needed individually.
A third option is to create a third bloc which subscribes to the first two blocs and aggregates the states into a single state.
Hope that helps 馃憤
If you're still having trouble please share a link to a github repo which reproduces the issue you're facing, thanks 馃檹
Thanks I used nested blocBuilder as in my code now and added the 2 events at app widget before didn't work but later worked.
Most helpful comment
Thanks I used nested blocBuilder as in my code now and added the 2 events at app widget before didn't work but later worked.