I'm using the BloC pattern for the first time in my App. And I am having multiple of problems with it.
For my Question i have a list of boolean ( Checkboxes ) The problem is when I click on the boxes sometimes they updated ( the correct behavior ) sometimes they does not updated ( wrong behavior )
The check box does not change until I click multiple times
Cubit Class
class FilterCubit extends Cubit<FilterState> {
FilterCubit() : super(const FilterInitial());
int sortByGV = 0;
void onSortByClick(int index) {
sortByGV = index;
emit(OnSortByState(index));
}
List<bool> choiceSportsList = [];
void fillChoiceSportsList(int length) {
for (int i = 0; i < length; i++) {
choiceSportsList.add(false);
}
}
void onChoiceSportClick(int index) {
if (choiceSportsList[index]) {
choiceSportsList[index] = false;
emit(const OnChoiceSportState(false));
} else {
choiceSportsList[index] = true;
emit(const OnChoiceSportState(true));
}
}
}
State Class
sealed class FilterState extends Equatable {
const FilterState();
@override
List<Object?> get props => [];
}
final class FilterInitial extends FilterState {
const FilterInitial();
@override
List<Object?> get props => [];
}
final class OnSortByState extends FilterState {
final int index;
const OnSortByState(this.index);
@override
List<Object?> get props => [index];
}
class OnChoiceSportState extends FilterState {
final bool val;
const OnChoiceSportState(this.val);
@override
List<Object?> get props => [val];
}
UI
showFilterBottomSheetComponent({double? heightFactor}) {
sl<FilterCubit>().fillChoiceSportsList(10);
return showModalBottomSheet<void>(
context: sl<NavigationService>().navigatorKey.currentContext!,
isScrollControlled: true,
builder: (BuildContext context) {
List<String> sports = [
'Padel',
'Soccer',
'Basketball',
'Tennis',
'Padbol',
'Pickleball',
'Volleyball',
'Badminton',
'Squash',
'Cricket'
];
return FractionallySizedBox(
heightFactor: heightFactor ?? 0.85,
child: BlocProvider(
create: (context) => sl<FilterCubit>(),
child: SafeArea(
child: Padding(
padding:
EdgeInsets.all(AppPadding.p24).copyWith(top: AppPadding.p16),
child: FilterChooseSportBody(data: sports),
),
),
),
);
},
);
}
class FilterChooseSportBody extends StatelessWidget {
const FilterChooseSportBody({
super.key,
required this.data,
});
final List<String> data;
@override
Widget build(BuildContext context) {
final filterC = BlocProvider.of<FilterCubit>(context, listen: true);
return Column(
children: [
for (int i = 0; i < data.length; i++)
CheckBoxListTileComponent(
title: data[i],
value: filterC.choiceSportsList[i],
onChanged: (value) {
filterC.onChoiceSportClick(i);
},
smallHeight: true,
style: getBodyMedium(),
),
],
);
}
}
In provider I have notifyListeners();
Do I need in bloc to create a state and emit it for each time??
Thanks.
I solved the problem with the following code.
First i removed the state class and replace it with List
Then the Cubit class like the following:
the UI widget
and in the above widget tree i added BlocProvider.value not BlocProvider
BlocProvider.value(value: cubit-here, child: .. )