You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Firebase问答应用:点击按钮后问题未刷新,updateQuestion方法异常

问题分析与解决方案:Android Firebase问答应用无法刷新问题内容

嘿,我一眼就瞅出问题根源了——你的mDatabaseReference从初始化开始就绑定死了第一个问题的节点,之后就算调用updateQuestion(),它也还是在监听旧节点,自然不会加载新内容!

核心问题拆解

你在onCreate里初始化mDatabaseReference时,用的是Question + mQuestionNumber(此时mQuestionNumber是1),之后每次调用updateQuestion(),这个引用都没有更新,始终指向第一个问题的数据库节点。所以不管题号怎么递增,展示的还是第一个问题的内容。

具体修改方案

我给你整理了优化后的代码,关键是把数据库引用的初始化移到updateQuestion()内部,同时封装重复的点击逻辑减少冗余:

// 先在类里声明成员变量,注意初始化题号和分数
private int mQuestionNumber = 1;
private int mScore = 0;
private DatabaseReference mDatabaseReference;
private ValueEventListener mQuestionListener; // 保存监听器,方便后续移除避免内存泄漏
private String answer; // 把答案设为成员变量,方便点击事件里调用

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.taking_quiz);

    que = (TextView) findViewById(R.id.txtQuestion);
    opt1 = (Button) findViewById(R.id.button1);
    opt2 = (Button) findViewById(R.id.button2);
    opt3 = (Button) findViewById(R.id.button3);
    opt4 = (Button) findViewById(R.id.button4);
    qn = (TextView) findViewById(R.id.number);
    sco = (TextView) findViewById(R.id.score);

    qn.setText("Question : 1");
    sco.setText("Score : 0");

    RecieversId = getIntent().getStringExtra("Recievers_Id");
    mAuth = FirebaseAuth.getInstance();
    currentUser = mAuth.getCurrentUser();

    // 统一设置选项点击事件,避免重复代码
    setupOptionClickListener(opt1);
    setupOptionClickListener(opt2);
    setupOptionClickListener(opt3);
    setupOptionClickListener(opt4);

    // 加载第一个问题
    updateQuestion();
}

private void updateQuestion() {
    // 先移除旧的监听器,防止内存泄漏和重复监听
    if (mDatabaseReference != null && mQuestionListener != null) {
        mDatabaseReference.removeEventListener(mQuestionListener);
    }

    // 根据最新的题号,获取对应数据库节点的引用
    mDatabaseReference = FirebaseDatabase.getInstance()
            .getReference()
            .child("Users")
            .child(RecieversId)
            .child("Quiz")
            .child("Question" + mQuestionNumber);

    mQuestionListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            // 判断当前题号对应的节点是否存在,不存在就跳转到结束页面
            if (!dataSnapshot.exists()) {
                Intent intent = new Intent(TakingQuiz.this, TakingQuizDone.class);
                intent.putExtra("Score", mScore);
                startActivity(intent);
                finish();
                return;
            }

            // 更新页面内容
            String question = dataSnapshot.child("Question").getValue().toString();
            answer = dataSnapshot.child("Answer").getValue().toString();
            String option1 = dataSnapshot.child("Option1").getValue().toString();
            String option2 = dataSnapshot.child("Option2").getValue().toString();
            String option3 = dataSnapshot.child("Option3").getValue().toString();
            String option4 = dataSnapshot.child("Option4").getValue().toString();

            que.setText(question);
            opt1.setText(option1);
            opt2.setText(option2);
            opt3.setText(option3);
            opt4.setText(option4);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Toast.makeText(TakingQuiz.this, "加载问题失败,请检查网络", Toast.LENGTH_SHORT).show();
        }
    };

    mDatabaseReference.addValueEventListener(mQuestionListener);
}

// 封装通用的选项点击逻辑,减少重复代码
private void setupOptionClickListener(final Button optionBtn) {
    optionBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String selectedOption = optionBtn.getText().toString();
            
            // 判断选项是否正确,更新分数和按钮颜色
            if (selectedOption.equals(answer)) {
                optionBtn.setBackgroundColor(Color.GREEN);
                mScore++;
                sco.setText("Score : " + mScore);
            } else {
                optionBtn.setBackgroundColor(Color.RED);
                sco.setText("Score : " + mScore);
            }

            // 延迟1.5秒后加载下一题
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    mQuestionNumber++;
                    qn.setText("Question : " + mQuestionNumber);
                    updateQuestion();
                    optionBtn.setBackgroundColor(Color.CYAN);
                }
            }, 1500);
        }
    });
}

额外注意点

  • 确保数据库里的节点命名和代码里的Question + mQuestionNumber完全匹配(比如Question1、Question2)
  • 每次加载新问题前移除旧监听器,能避免不必要的资源消耗和内存泄漏
  • 在onDataChange里判断节点是否存在,能实现自动跳转到结束页面的逻辑

内容的提问来源于stack exchange,提问作者user9646251

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:45:55