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

Kotlin计时器跳转异常:问答App计时器结束后题目来回跳转求助

问答应用计时器跳转异常修复方案

问题分析

当前代码存在三个核心问题导致跳转异常:

  1. 计时器onTick滥用跳转:除Memes外的所有分类,在计时器每一秒的onTick回调中直接调用nextActivity,导致每秒都触发页面跳转,引发页面来回切换。
  2. 局部变量覆盖全局变量:Music、Movies and Tv等分类分支中,重新定义了questionNumber和currentScore局部变量,覆盖了Activity全局的变量值,导致传递到下一题的序号和分数错误。
  3. 计时器跳转逻辑错误:Memes分类在onTick中判断时间为0才跳转,但onTick的最后一次回调是剩余1秒,永远不会触发0的判断,且所有分类的跳转逻辑应该统一放在onFinish中执行。

修复后的完整代码

package com.example.recognition
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.os.CountDownTimer
import android.util.Log
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import com.example.recognition.databinding.ActivityQuestionsBinding
import com.example.recognition.models.Constants.LogoQuestions
import com.example.recognition.models.Constants.getAllCelebQuestions
import com.example.recognition.models.Constants.getMemeQuestions
import com.example.recognition.models.Constants.getMusicQuestions
import com.example.recognition.models.Constants.getTvQuestions
import com.example.recognition.models.Question

class QuestionsActivity : AppCompatActivity() {
    private lateinit var binding: ActivityQuestionsBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityQuestionsBinding.inflate(layoutInflater)
        setContentView(binding.root)
        val username = intent.getStringExtra("username").toString()
        val category = intent.getStringExtra("Category").toString()
        var questionNumber: Int = intent.getIntExtra("number", 0)
        var currentScore = intent.getIntExtra("currentScore", 0)
        Log.i("InitialVals", "$questionNumber,$category,$username,$currentScore")
        Log.i("Category Name", category)
        window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
        actionBar?.hide()

        // 统一获取当前分类的题目列表
        val questions = when(category) {
            "Memes" -> getMemeQuestions()
            "Music" -> getMusicQuestions()
            "Movies and Tv" -> getTvQuestions()
            "Celebrities" -> getAllCelebQuestions()
            "Logos" -> LogoQuestions()
            else -> arrayListOf()
        }
        val currQuestion = questions[questionNumber]
        updateUI(username, currQuestion)

        // 统一设置选项点击事件,避免重复代码
        binding.answerOne.setOnClickListener {
            val isCorrect = category == "Memes"
            handleAnswerClick(it, isCorrect, currentScore, questionNumber, category, username, questions)
        }

        binding.answerTwo.setOnClickListener {
            val isCorrect = category == "Logos"
            handleAnswerClick(it, isCorrect, currentScore, questionNumber, category, username, questions)
        }

        binding.answerThree.setOnClickListener {
            val isCorrect = category == "Movies and Tv"
            handleAnswerClick(it, isCorrect, currentScore, questionNumber, category, username, questions)
        }

        binding.answerFour.setOnClickListener {
            val isCorrect = category == "Celebrities"
            handleAnswerClick(it, isCorrect, currentScore, questionNumber, category, username, questions)
        }

        Log.i("Score", "${currentScore}/${questions.count()}")

        binding.settingsButton.setOnClickListener{
            val intent = Intent(this, Settings::class.java)
            startActivity(intent)
            finish()
        }

        // 修复后的计时器逻辑
        object : CountDownTimer(11000,1000){
            override fun onTick(millisUntilFinished: Long){
                val remainingSeconds = (millisUntilFinished / 1000).toInt()
                binding.timerText.text = remainingSeconds.toString()
                // 仅处理计时器颜色变化,不涉及跳转
                when {
                    remainingSeconds < 3 -> binding.timerText.setTextColor(Color.RED)
                    remainingSeconds < 5 -> binding.timerText.setTextColor(Color.YELLOW)
                    else -> binding.timerText.setTextColor(Color.WHITE)
                }
            }

            override fun onFinish(){
                binding.timerText.setTextColor(Color.RED)
                binding.timerText.text = "0"
                Log.i("Values", "$questionNumber,$category,$username,$currentScore")
                // 计时器结束后统一跳转,不加分
                nextActivity(questionNumber, category, username, currentScore, questions)
            }
        }.start()
    }

    // 统一处理选项点击逻辑,减少重复代码
    private fun handleAnswerClick(view: View, isCorrect: Boolean, currentScore: Int, questionNumber: Int, category: String, username: String, questions: ArrayList<Question>) {
        var updatedScore = currentScore
        if(isCorrect) {
            view.setBackgroundColor(Color.parseColor("#64CB40"))
            updatedScore += 1
        } else {
            view.setBackgroundColor(Color.parseColor("#EE3A57"))
        }
        nextActivity(questionNumber, category, username, updatedScore, questions)
    }

    fun nextActivity( questionNumber: Int, category: String, username: String, currentScore: Int, questions: ArrayList<Question> ){
        if(questionNumber+1 == questions.count()){
            val intent = Intent(this, ResultsActivity::class.java)
            intent.putExtra("Category", category)
            intent.putExtra("username", username)
            intent.putExtra("currentScore", currentScore)
            startActivity(intent)
            finish()
        } else{
            val intent = Intent(this, QuestionsActivity::class.java)
            intent.putExtra("number", questionNumber+1)
            intent.putExtra("Category", category)
            intent.putExtra("username", username)
            intent.putExtra("currentScore", currentScore)
            startActivity(intent)
            finish()
        }
    }

    fun updateUI(username: String, currentQuestion: Question){
        val category = intent.getStringExtra("Category").toString()
        binding.nameText.text = if(currentQuestion.id == 1) {
            "Okay $username, ${currentQuestion.QuestionTxt}"
        } else {
            currentQuestion.QuestionTxt
        }
        binding.textView.text = category
        binding.imageContainer.setImageResource(currentQuestion.QuestionImg)
        binding.answerOne.text = currentQuestion.OptionOne
        binding.answerTwo.text = currentQuestion.OptionTwo
        binding.answerThree.text = currentQuestion.OptionThree
        binding.answerFour.text = currentQuestion.OptionFour
    }
}

修复要点说明

  1. 统一题目列表获取:将各分类的题目列表获取逻辑抽离到when表达式中,避免重复代码,同时确保全局变量questionNumber和currentScore不被局部变量覆盖。
  2. 重构选项点击逻辑:新增handleAnswerClick方法统一处理选项点击,减少重复代码,同时正确计算分数。
  3. 修正计时器逻辑:仅在onFinish方法中执行跳转操作,onTick只处理计时器颜色变化,避免每秒触发跳转。
  4. 修复Memes分类跳转判断:原来的onTick中判断时间为0的逻辑无效,现在统一在onFinish处理,确保计时器结束后必然跳转。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 05:54:09