Kotlin中屏幕旋转后如何恢复GridLayout游戏计分表状态?
问题分析与解决方案
1. 修复监听器绑定失效问题
- 屏幕旋转后Activity重建,旧视图已被销毁,新生成的GridLayout子视图必须重新绑定点击/文本变化监听器,不能复用之前的视图引用。
- 遍历新创建的GridLayout所有子视图,为每个输入控件(比如EditText)绑定监听器,同时用
tag存储对应Cell实体,方便后续获取正确的数据库字段:// 遍历GridLayout绑定监听器示例 for (i in 0 until gridLayout.childCount) { val view = gridLayout.getChildAt(i) if (view is EditText) { view.setOnFocusChangeListener { v, hasFocus -> if (!hasFocus) { val cell = v.tag as Cell updateScoreToDb(cell.cellId, cell.gameInstanceId, view.text.toString().toInt()) } } } }
2. 解决外键约束冲突
- 外键问题通常是因为重建时关联的
GameInstanceId/playerId错误,或者保存分数时使用了新生成的CellId而非数据库中已有的ID。 - 重建前先从数据库查询当前
GameInstanceId对应的所有Cell数据,逐个填充单元格时,把查询到的Cell实体通过tag绑定到视图上,保存分数时直接用该实体的CellId和关联ID,避免手动生成错误的关联值。
3. 正确保存与恢复Activity状态
- 用
onSaveInstanceState和onRestoreInstanceState保存关键状态(当前GameInstanceId、玩家数、当前回合数),重建时直接读取这些值,快速定位要加载的数据库数据:override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putLong("gameId", currentGameId) outState.putInt("playerNum", playerCount) outState.putInt("roundNum", currentRound) } override fun onRestoreInstanceState(savedInstanceState: Bundle) { super.onRestoreInstanceState(savedInstanceState) currentGameId = savedInstanceState.getLong("gameId") playerCount = savedInstanceState.getInt("playerNum") currentRound = savedInstanceState.getInt("roundNum") rebuildScoreGrid() } - 重建计分表前先清空GridLayout的旧内容,避免新旧视图混合导致的逻辑混乱。
4. 校准动态添加行的逻辑
- 动态添加新行时,以数据库中当前游戏实例的最大回合数为起点,而非从头计数,确保新行的
roundNumber能正确关联到现有游戏实例,避免外键错误。
内容的提问来源于stack exchange,提问作者Christof Plieschnegger
相关产品推荐
相关产品推荐

