I Using cubit on my project. I simply want to choose some elements and show it in next page.But store it in cubit too for i can use later. But when i choose an element its going to cubit and emitting state. But BlocBuilder doesn't refresh itself and doesnt rebuild my widget. What can i do about it ?
My Code :
Cubit
class TherapyCubit extends Cubit<TherapyState> {
TherapyCubit() : super(TherapyInitial());
List<Therapy> selectedTherapies = [];
void addTherapy(Therapy therapy) {
selectedTherapies.add(therapy);
// inspect(selectedTherapies);
emit(SelectedTherapy(therapy: selectedTherapies));
}
void deleteTherapy(Therapy therapy) {
selectedTherapies.remove(therapy);
emit(SelectedTherapy(therapy: selectedTherapies));
}
}
Cubit State
abstract class TherapyState extends Equatable {
const TherapyState();
@override
List<Object> get props => [];
}
class TherapyInitial extends TherapyState {}
class SelectedTherapy extends TherapyState {
final List<Therapy> therapy;
const SelectedTherapy({required this.therapy});
@override
List<Object> get props => [therapy];
}
UI
List of my custom widget :
Wrap(
spacing: 16,
runSpacing: 16,
alignment: WrapAlignment.center,
children: [
for (final therapy in therapyList)
BlocBuilder<TherapyCubit, TherapyState>(
bloc: TherapyCubit(),
builder: (context, state) {
if (state is SelectedTherapy) {
inspect(state.therapy); //cant see it
}
return EllipsisCard( // I want to rebuild it whenever i choose a ellipsis card so it can be purple.
therapy: therapy,
);
},
)
],
)
My Custom Widget :
class _EllipsisCardState extends State<EllipsisCard> {
@override
Widget build(BuildContext context) {
List<Therapy> selectedTherapies = context.read<TherapyCubit>().selectedTherapies;
bool isHave = selectedTherapies.contains(widget.therapy);
return InkWell(
onTap: () {
if (!isHave) {
print("girdi");
context.read<TherapyCubit>().addTherapy(widget.therapy);
} else {
context.read<TherapyCubit>().deleteTherapy(widget.therapy);
}
},
child: Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100),
border: Border.all(color: isHave ? ColorService.purple : ColorService.grayBorderColor),
color: isHave ? ColorService.purpleHalfOpacityBackground : Colors.white,
),
child: Text(
widget.therapy.name ?? "Unknown",
style: TextStyle(color: isHave ? ColorService.purple : ColorService.blackText, letterSpacing: 0.1, fontSize: 14, fontWeight: isHave ? FontWeight.w500 : FontWeight.w400),
),
),
);
}
}
Where do i making wrong ? Thanks for help ! :))
CodePudding user response:
Emit the copy of your list in order to recognize the change in state, like:
void addTherapy(Therapy therapy) {
selectedTherapies.add(therapy);
// inspect(selectedTherapies);
emit(SelectedTherapy(therapy: List.of(selectedTherapies)));
}
void deleteTherapy(Therapy therapy) {
selectedTherapies.remove(therapy);
emit(SelectedTherapy(therapy: List.of(selectedTherapies)));
}
So, the complete solution would be something like this:
class Test extends StatefulWidget {
const Test({Key? key}) : super(key: key);
@override
State<Test> createState() => _TestState();
}
class _TestState extends State<Test> {
late List<Therapy> therapyList = [
Therapy('one'),
Therapy('two'),
Therapy('three'),
Therapy('four'),
];
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: Column(
children: [
Wrap(
spacing: 16,
runSpacing: 16,
alignment: WrapAlignment.center,
children: [
for (final therapy in therapyList)
BlocBuilder<TherapyCubit, TherapyState>(
builder: (context, state) {
return EllipsisCard(
therapy: therapy,
);
},
)
],
)
],
),
),
),
);
}
}
class TherapyCubit extends Cubit<TherapyState> {
TherapyCubit() : super(TherapyInitial());
List<Therapy> selectedTherapies = [];
void addTherapy(Therapy therapy) {
selectedTherapies.add(therapy);
// inspect(selectedTherapies);
emit(SelectedTherapy(therapy: List.of(selectedTherapies)));
}
void deleteTherapy(Therapy therapy) {
selectedTherapies.remove(therapy);
emit(SelectedTherapy(therapy: List.of(selectedTherapies)));
}
}
abstract class TherapyState extends Equatable {
const TherapyState();
@override
List<Object> get props => [];
}
class TherapyInitial extends TherapyState {}
class SelectedTherapy extends TherapyState {
final List<Therapy> therapy;
const SelectedTherapy({required this.therapy});
@override
List<Object> get props => [therapy];
}
class EllipsisCard extends StatelessWidget {
final Therapy therapy;
EllipsisCard({required this.therapy, Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
List<Therapy> selectedTherapies =
context.read<TherapyCubit>().selectedTherapies;
bool isHave = selectedTherapies.contains(therapy);
return InkWell(
onTap: () {
if (!isHave) {
context.read<TherapyCubit>().addTherapy(therapy);
} else {
context.read<TherapyCubit>().deleteTherapy(therapy);
}
},
child: Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100),
color: isHave ? Colors.purple : Colors.white,
),
child: Text(
therapy.name ?? "Unknown",
style: TextStyle(
letterSpacing: 0.1,
fontSize: 14,
fontWeight: isHave ? FontWeight.w500 : FontWeight.w400),
),
),
);
}
}