如何仅使用saveInstanceState替代SharedPreference处理游戏旋转时分数保存
问题分析与解决
你的代码中每次启动onCreate都会从SharedPreference读取分数,覆盖了saveInstanceState恢复的值,这是导致只用saveInstanceState失效的核心原因。同时你还保留了所有SharedPreference的写入逻辑,进一步干扰了状态恢复流程。
修改步骤
- 删除所有
SharedPreference相关的代码(包括初始化、读取、写入操作) - 在
onCreate中优先从savedInstanceState恢复count值,没有则初始化为0 - 恢复
count后同步更新UI(文本内容、颜色)和按钮可用性状态 - 保留
onSaveInstanceState的逻辑,确保旋转时保存当前分数
修改后的完整代码
import android.graphics.Color import android.media.MediaPlayer import android.os.Bundle import android.util.Log import android.widget.Button import android.widget.TextView import androidx.appcompat.app.AppCompatActivity class MainActivity : AppCompatActivity() { override fun onStart() { super.onStart() Log.i("TAG", "onStart") } var count = 0 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) Log.i("TAG", "onCreate") val scoreBtn = findViewById<Button>(R.id.btn_score) val stealBtn = findViewById<Button>(R.id.btn_steal) val resetBtn = findViewById<Button>(R.id.btn_reset) val resultTv = findViewById<TextView>(R.id.result) // 从savedInstanceState恢复count,没有则初始化为0 if (savedInstanceState != null) { count = savedInstanceState.getInt("MyInt", 0) } Log.i("TAG", "当前分数: $count") // 初始化UI状态 resultTv.text = count.toString() check(count, resultTv) checkBounds(scoreBtn, stealBtn) var mediaPlayer = MediaPlayer.create(this, R.raw.success_1_6297) if (count == 15) { mediaPlayer.start() } scoreBtn.setOnClickListener { count++ resultTv.text = count.toString() check(count, resultTv) checkBounds(scoreBtn, stealBtn) if (count == 15) { mediaPlayer.start() } } stealBtn.setOnClickListener { count-- resultTv.text = count.toString() check(count, resultTv) checkBounds(scoreBtn, stealBtn) } resetBtn.setOnClickListener { count = 0 resultTv.text = count.toString() check(count, resultTv) checkBounds(scoreBtn, stealBtn) } } fun check(incrementNumber: Int, result: TextView) { result.setTextColor( when { incrementNumber >= 10 -> Color.GREEN incrementNumber >= 5 -> Color.BLUE else -> Color.BLACK } ) } // 把checkBounds改为带参数的函数,避免依赖局部变量 fun checkBounds(scoreBtn: Button, stealBtn: Button) { scoreBtn.isEnabled = count < 15 stealBtn.isEnabled = count > 0 } override fun onSaveInstanceState(savedInstanceState: Bundle) { super.onSaveInstanceState(savedInstanceState) // 保存当前分数到Bundle savedInstanceState.putInt("MyInt", count) } // 可选:也可以在onRestoreInstanceState中恢复,但onCreate中已经处理,这里可以删除或者保留 override fun onRestoreInstanceState(savedInstanceState: Bundle) { super.onRestoreInstanceState(savedInstanceState) count = savedInstanceState.getInt("MyInt", 0) // 如果保留这个方法,需要重新更新UI和按钮状态 val resultTv = findViewById<TextView>(R.id.result) val scoreBtn = findViewById<Button>(R.id.btn_score) val stealBtn = findViewById<Button>(R.id.btn_steal) resultTv.text = count.toString() check(count, resultTv) checkBounds(scoreBtn, stealBtn) } }
关键说明
- 状态恢复优先级:在
onCreate中先判断savedInstanceState是否存在,存在则优先恢复,确保旋转后的分数正确 - UI同步:恢复
count后必须立即更新TextView文本、颜色和按钮可用性,保证界面状态和数据一致 - 移除SharedPreference:完全删除SharedPreference相关代码,避免和saveInstanceState的状态冲突
checkBounds优化:改为带参数的函数,避免依赖onCreate中的局部变量,提升代码健壮性
内容的提问来源于stack exchange,提问作者ACN
相关产品推荐
相关产品推荐

