Kotlin计时器跳转异常:问答App计时器结束后题目来回跳转求助
问答应用计时器跳转异常修复方案
问题分析
当前代码存在三个核心问题导致跳转异常:
- 计时器
onTick滥用跳转:除Memes外的所有分类,在计时器每一秒的onTick回调中直接调用nextActivity,导致每秒都触发页面跳转,引发页面来回切换。 - 局部变量覆盖全局变量:Music、Movies and Tv等分类分支中,重新定义了
questionNumber和currentScore局部变量,覆盖了Activity全局的变量值,导致传递到下一题的序号和分数错误。 - 计时器跳转逻辑错误: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 } }
修复要点说明
- 统一题目列表获取:将各分类的题目列表获取逻辑抽离到when表达式中,避免重复代码,同时确保全局变量
questionNumber和currentScore不被局部变量覆盖。 - 重构选项点击逻辑:新增
handleAnswerClick方法统一处理选项点击,减少重复代码,同时正确计算分数。 - 修正计时器逻辑:仅在
onFinish方法中执行跳转操作,onTick只处理计时器颜色变化,避免每秒触发跳转。 - 修复Memes分类跳转判断:原来的
onTick中判断时间为0的逻辑无效,现在统一在onFinish处理,确保计时器结束后必然跳转。
内容的提问来源于stack exchange,提问作者DevAcc
相关产品推荐
相关产品推荐

