Android问题:RadioButton屏幕旋转后未重置选中状态
旋转屏幕后RadioGroup日志与界面选中状态不符的原因及解决办法
问题场景
应用启动时RadioButton A默认选中,选中B后旋转屏幕,预期会恢复默认的A选项。日志显示radioButtonGroup.checkedRadioButtonId确实是A的ID,但界面上却仍显示B处于选中状态,未手动保存状态却出现这种矛盾情况。
布局代码
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <LinearLayout android:id="@+id/employment_button_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:orientation="vertical" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> <RadioGroup android:id="@+id/radio_button_group" android:layout_width="match_parent" android:layout_height="match_parent"> <RadioButton android:id="@+id/a_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:checked="true" android:onClick="onClick" android:text="A" /> <RadioButton android:id="@+id/b_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="onClick" android:text="B" /> <RadioButton android:id="@+id/c_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="onClick" android:text="C" /> </RadioGroup> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout>
Activity代码
package com.cs211d.loanreview import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log import android.view.View import android.widget.RadioButton import android.widget.RadioGroup class MainActivity : AppCompatActivity() { private lateinit var radioButtonGroup : RadioGroup private lateinit var aButton : RadioButton private lateinit var bButton : RadioButton private lateinit var cButton : RadioButton override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) radioButtonGroup = findViewById(R.id.radio_button_group) aButton = findViewById(R.id.a_button) bButton = findViewById(R.id.b_button) cButton = findViewById(R.id.c_button) Log.d("oncreate", radioButtonGroup.checkedRadioButtonId.toString()) } fun onClick (view : View){ Log.d("TESTING evaluate status", radioButtonGroup.checkedRadioButtonId.toString()) } }
原因分析
这是Android系统的View自动状态保存机制导致的:
- 系统会自动为带有
android:id的View保存和恢复状态,RadioGroup、RadioButton都属于这类控件,会记住你之前选中的选项。 - 你在
onCreate中打印日志的时机是布局刚加载完成,此时布局里android:checked="true"的配置先生效,所以日志显示A的ID。但在onCreate之后,系统会通过onRestoreInstanceState流程,把之前选中B的状态恢复回来,最终界面显示B选中,和日志产生了矛盾。
解决办法
如果希望旋转屏幕后强制恢复默认选中A,有两种可行方案:
方案1:禁止RadioGroup自动保存状态
在布局的RadioGroup标签中添加android:saveEnabled="false",让系统不再自动保存它的选中状态,旋转后会保持布局默认的A选中:
<RadioGroup android:id="@+id/radio_button_group" android:layout_width="match_parent" android:layout_height="match_parent" android:saveEnabled="false">
方案2:手动覆盖恢复后的状态
重写onRestoreInstanceState方法,在系统完成状态恢复后,手动设置选中A按钮,覆盖系统恢复的状态:
override fun onRestoreInstanceState(savedInstanceState: Bundle?) { super.onRestoreInstanceState(savedInstanceState) // 强制选中A radioButtonGroup.check(R.id.a_button) }
也可以选择在onStart方法中设置,因为onStart是在状态恢复流程之后执行的:
override fun onStart() { super.onStart() radioButtonGroup.check(R.id.a_button) }
内容的提问来源于stack exchange,提问作者JLM
相关产品推荐
相关产品推荐

