I am building a demo quiz app in flutter using Bloc, The data is shown and I am trying to update the question and it’s options. The widget isn’t rebuilding I think. Everytime i click on a option, it should move to the next question, but it doesn’t show any changes in the UI. it changes the question after I press hot reload.
class QuizCubit extends Cubit<QuizState> {
QuizCubit() : super(QuizInitialState()) {
drawQuizData();
}
QuizBrain quizBrain = QuizBrain();
late QuizResult result;
drawQuizData() async {
emit(QuizLoadingDemoState());
await Future.delayed(
const Duration(seconds: 1),
);
emit(QuizDataState(
quizBrain: quizBrain,
));
}
void pickedOption() {
quizBrain.toNextQuestion();
if (quizBrain.isLastQuestion()) {
emit(QuizQuizCompletedState());
} else {
emit(QuizPickedOptionState());
}
}
}
pickedOption
is the function responsible
The quiz logic is fine as it is working without bloc without any issues.
Scaffold(
backgroundColor: Colors.white,
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
BlocConsumer<QuizCubit, QuizState>(
listener: (context, state) {
if (state is QuizQuizCompletedState) {
// Handle quiz completion here.
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: const Row(
children: [
Icon(
Icons.info_outline,
color: Colors.white,
),
SizedBox(width: 12.0),
Text(
"Success",
style: TextStyle(
color: Colors.white,
fontSize: 16.0,
fontWeight: FontWeight.bold),
),
],
),
backgroundColor: Colors.green.shade300,
duration: const Duration(seconds: 3),
action: SnackBarAction(
label: 'Close',
textColor: Colors.white,
onPressed: () {
// Add any action you want here
ScaffoldMessenger.of(context).hideCurrentSnackBar();
},
),
),
);
}
},
listenWhen: (previous, current) => current is QuizActionState,
bloc: quizCubit,
buildWhen: (previous, current) => current is! QuizActionState,
builder: (context, state) {
if (state is QuizLoadingDemoState) {
return const CupertinoActivityIndicator();
}
if (state is QuizPickedOptionState) {
// emit();
return const CircularProgressIndicator();
}
if (state is QuizDataState) {
return Column(
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"${state.quizBrain.questionNumber + 1}: ",
style: const TextStyle(fontWeight: FontWeight.bold),
),
Text(
state.quizBrain.quizQuestion(),
style: const TextStyle(fontWeight: FontWeight.bold),
),
],
),
SizedBox(
height: 120,
width: 210,
child: ListView.builder(
itemCount: state.quizBrain.quizOptions().length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
// quizCubit.pickedOption(
// state.quizBrain.quizOptions()[index],
// );
quizCubit.pickedOption(
);
},
child: Text(
state.quizBrain.quizOptions()[index],
style: const TextStyle(
fontWeight: FontWeight.bold),
),
);
},
),
),
],
);
}
return const Text("123");
},
),
],
),
),
);
quizCubit.pickedOption(
);
2
Answers
I solved the answer myself. The answer to it is instead of emitting the new state, I just emitted the old state again.
Here is the code for it.
Your issue seems to be from the state management in your
QuizCubit
. When you call thepickedOption
function, you are updating theQuizBrain
object, but this doesn’t necessarily trigger a re-render of the widget because you’re only emitting theQuizPickedOptionState()
or theQuizQuizCompletedState()
without carrying over the updated data.Here are a few steps you can take to resolve this issue:
QuizCubit
, make sure it carries the updated data. For instance, you could include the updatedQuizBrain
object in both theQuizPickedOptionState
andQuizQuizCompletedState
.Update your
pickedOption
method to include the updatedquizBrain
:Now, in your
BlocConsumer
, you should account for the states you modified:With these changes, your widget should be able to re-render and show updated data whenever there’s a state change in your
QuizCubit
.Lastly, ensure that the methods within
QuizBrain
(e.g.,toNextQuestion
,quizQuestion
, andquizOptions
) are functioning correctly and returning the expected data.