Home > Enterprise >  Flutter Cubit Bloc builder doesnt trigger after emit
Flutter Cubit Bloc builder doesnt trigger after emit

Time:04-27

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),
        ),
      ),
    );
  }
}
  • Related