flutter Bloc没有更新小部件树

uplii1fm  于 2023-10-22  发布在  Flutter
关注(0)|答案(2)|浏览(130)

我正在建立一个演示问答应用程序在Flutter使用集团,数据显示,我试图更新的问题,它的选项.我想这个小部件不会重建了。每次我点击一个选项,它应该移动到下一个问题,但它不显示任何变化的UI。我按下热重装后问题就变了

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

测试逻辑很好,因为它在没有阻塞的情况下工作,没有任何问题。

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(
                                        );
tvokkenx

tvokkenx1#

您的问题似乎来自QuizCubit中的状态管理。当调用pickedOption函数时,您正在更新QuizBrain对象,但这并不一定会触发小部件的重新呈现,因为您只是发出QuizPickedOptionState()QuizQuizCompletedState(),而没有携带更新的数据。
以下是您可以采取的几个步骤来解决此问题:
1.修改状态以包括更新的数据:每次从QuizCubit发出新状态时,确保它携带更新的数据。例如,您可以在QuizPickedOptionStateQuizQuizCompletedState中包含更新的QuizBrain对象。

class QuizPickedOptionState extends QuizState {
  final QuizBrain quizBrain;
  QuizPickedOptionState({required this.quizBrain});
}

class QuizQuizCompletedState extends QuizState {
  final QuizBrain quizBrain;
  QuizQuizCompletedState({required this.quizBrain});
}

1.发送具有更新数据的状态
更新您的pickedOption方法以包含更新的quizBrain

void pickedOption() {
  quizBrain.toNextQuestion();
  if (quizBrain.isLastQuestion()) {
    emit(QuizQuizCompletedState(quizBrain: quizBrain));
  } else {
    emit(QuizPickedOptionState(quizBrain: quizBrain));
  }
}

1.更新Widget渲染逻辑
现在,在您的BlocConsumer中,您应该考虑您修改的状态:

//...
builder: (context, state) {
  if (state is QuizLoadingDemoState) {
    return const CupertinoActivityIndicator();
  }
  if (state is QuizPickedOptionState || state is QuizDataState || state is QuizQuizCompletedState) {
    var quizBrainToUse = state is QuizDataState 
        ? state.quizBrain 
        : (state is QuizPickedOptionState ? state.quizBrain : null);
        
    // Return your UI here using `quizBrainToUse`.
    // ...
  }
  return const Text("123");
}
//...

通过这些更改,您的小部件应该能够在QuizCubit中发生状态更改时重新呈现和显示更新的数据。
最后,确保QuizBrain中的方法(例如toNextQuestionquizQuestionquizOptions)正确运行并返回预期的数据。

n9vozmp4

n9vozmp42#

我自己解决了问题。它的答案是,而不是发出新的状态,我只是再次发出旧的状态。
下面是它的代码。

void pickedOption() {
    quizBrain.toNextQuestion();
    if (quizBrain.isLastQuestion()) {
      quizBrain.reset();
      emit(QuizQuizCompletedState());
    } else {
      emit(QuizDataState(quizBrain: quizBrain));
    }
  }

相关问题