如何利用onSaveInstanceState和onRestoreInstanceState保存单选、复选框选中状态?
解决屏幕旋转时测验控件状态丢失的问题
看起来你已经找对了方向——用onSaveInstanceState和onRestoreInstanceState来保存状态,但目前的代码只处理了正确答案的颜色,没保存RadioButton、CheckBox的选中状态,也没留存EditText的输入内容。咱们一步步来修复这个问题:
第一步:声明成员变量存储关键状态
先把需要跨生命周期保存的变量改成Activity的成员变量,这样各个生命周期方法都能访问到:
public class Activity1 extends AppCompatActivity { // 控件声明 private Button finishButton; private EditText enterName, answer1; private RadioButton answer2, answer3, answer5; private CheckBox answer41, answer42, answer43, answer44, answer45; // 新增成员变量存储状态 private boolean isQuizFinished = false; // 标记是否点击过「完成」按钮 private String answer1Input; private boolean answer2Checked, answer3Checked, answer5Checked; private boolean answer41Checked, answer42Checked, answer43Checked, answer44Checked, answer45Checked; private boolean isQ1Correct, isQ2Correct, isQ3Correct, isQ4Correct, isQ5Correct; // ... 其他代码 }
第二步:完善onSaveInstanceState方法
在这个方法里,把所有需要保留的状态存入Bundle:
@Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); // 保存EditText输入内容 outState.putString("answer1Input", answer1.getText().toString()); outState.putString("userName", enterName.getText().toString()); // 保存RadioButton选中状态 outState.putBoolean("answer2Checked", answer2.isChecked()); outState.putBoolean("answer3Checked", answer3.isChecked()); outState.putBoolean("answer5Checked", answer5.isChecked()); // 保存CheckBox选中状态 outState.putBoolean("answer41Checked", answer41.isChecked()); outState.putBoolean("answer42Checked", answer42.isChecked()); outState.putBoolean("answer43Checked", answer43.isChecked()); outState.putBoolean("answer44Checked", answer44.isChecked()); outState.putBoolean("answer45Checked", answer45.isChecked()); // 保存测验完成状态和题目对错标记 outState.putBoolean("isQuizFinished", isQuizFinished); outState.putBoolean("isQ1Correct", isQ1Correct); outState.putBoolean("isQ2Correct", isQ2Correct); outState.putBoolean("isQ3Correct", isQ3Correct); outState.putBoolean("isQ4Correct", isQ4Correct); outState.putBoolean("isQ5Correct", isQ5Correct); }
第三步:恢复状态并复用颜色设置逻辑
我们在onCreate里先判断是否有保存的状态,然后逐一恢复;同时把设置正确答案颜色的逻辑抽成方法,避免重复代码:
1. 新增颜色设置复用方法
private void setCorrectAnswerColors() { // 设置正确的EditText颜色 if (isQ1Correct) { answer1.setTextColor(0xAA76FF03); } // 设置正确的RadioButton颜色 if (isQ2Correct) answer2.setTextColor(0xAA76FF03); if (isQ3Correct) answer3.setTextColor(0xAA76FF03); if (isQ5Correct) answer5.setTextColor(0xAA76FF03); // 设置正确的CheckBox颜色 if (isQ4Correct) { answer42.setTextColor(0xAA76FF03); answer43.setTextColor(0xAA76FF03); answer44.setTextColor(0xAA76FF03); answer45.setTextColor(0xAA76FF03); } }
2. 在onCreate中恢复状态
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.html_new_page); // 初始化控件(原有代码) finishButton = findViewById(R.id.finish_button); enterName = findViewById(R.id.enter_name); answer1 = findViewById(R.id.answer_1); answer2 = findViewById(R.id.answer2); answer3 = findViewById(R.id.answer3); answer5 = findViewById(R.id.answer5); answer41 = findViewById(R.id.answer41); answer42 = findViewById(R.id.answer42); answer43 = findViewById(R.id.answer43); answer44 = findViewById(R.id.answer44); answer45 = findViewById(R.id.answer45); // 恢复保存的状态 if (savedInstanceState != null) { // 恢复EditText内容 answer1Input = savedInstanceState.getString("answer1Input"); answer1.setText(answer1Input); enterName.setText(savedInstanceState.getString("userName")); // 恢复RadioButton选中状态 answer2Checked = savedInstanceState.getBoolean("answer2Checked"); answer2.setChecked(answer2Checked); answer3Checked = savedInstanceState.getBoolean("answer3Checked"); answer3.setChecked(answer3Checked); answer5Checked = savedInstanceState.getBoolean("answer5Checked"); answer5.setChecked(answer5Checked); // 恢复CheckBox选中状态 answer41Checked = savedInstanceState.getBoolean("answer41Checked"); answer41.setChecked(answer41Checked); answer42Checked = savedInstanceState.getBoolean("answer42Checked"); answer42.setChecked(answer42Checked); answer43Checked = savedInstanceState.getBoolean("answer43Checked"); answer43.setChecked(answer43Checked); answer44Checked = savedInstanceState.getBoolean("answer44Checked"); answer44.setChecked(answer44Checked); answer45Checked = savedInstanceState.getBoolean("answer45Checked"); answer45.setChecked(answer45Checked); // 恢复测验完成状态和对错标记 isQuizFinished = savedInstanceState.getBoolean("isQuizFinished"); isQ1Correct = savedInstanceState.getBoolean("isQ1Correct"); isQ2Correct = savedInstanceState.getBoolean("isQ2Correct"); isQ3Correct = savedInstanceState.getBoolean("isQ3Correct"); isQ4Correct = savedInstanceState.getBoolean("isQ4Correct"); isQ5Correct = savedInstanceState.getBoolean("isQ5Correct"); // 如果已经完成测验,显示正确答案颜色 if (isQuizFinished) { setCorrectAnswerColors(); } } // 原有「完成」按钮点击事件(稍作修改) finishButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { isQuizFinished = true; answer1Input = answer1.getText().toString(); answer2Checked = answer2.isChecked(); answer3Checked = answer3.isChecked(); answer41Checked = answer41.isChecked(); answer42Checked = answer42.isChecked(); answer43Checked = answer43.isChecked(); answer44Checked = answer44.isChecked(); answer45Checked = answer45.isChecked(); answer5Checked = answer5.isChecked(); // 判断题目对错 isQ1Correct = answer1Input.equals("Hypertext Markup Language") || answer1Input.equals("HyperText Markup Language"); isQ2Correct = answer2Checked; isQ3Correct = answer3Checked; isQ5Correct = answer5Checked; isQ4Correct = !answer41Checked && answer42Checked && answer43Checked && answer44Checked && answer45Checked; // 设置正确答案颜色 setCorrectAnswerColors(); // 计算得分并跳转(原有代码) int correctNumber = (isQ1Correct ? 1 : 0) + (isQ2Correct ? 1 : 0) + (isQ3Correct ? 1 : 0) + (isQ4Correct ? 1 : 0) + (isQ5Correct ? 1 : 0); String correct = Integer.toString(correctNumber); Intent i = new Intent(Activity1.this, ResultActivity.class); i.putExtra("outData", enterName.getText().toString()); i.putExtra("out", correct); startActivity(i); } }); }
可选:补充onRestoreInstanceState方法
如果你习惯在onRestoreInstanceState里处理状态恢复,也可以添加这段代码(逻辑和onCreate里的恢复部分一致):
@Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); answer1Input = savedInstanceState.getString("answer1Input"); answer1.setText(answer1Input); enterName.setText(savedInstanceState.getString("userName")); answer2Checked = savedInstanceState.getBoolean("answer2Checked"); answer2.setChecked(answer2Checked); answer3Checked = savedInstanceState.getBoolean("answer3Checked"); answer3.setChecked(answer3Checked); answer5Checked = savedInstanceState.getBoolean("answer5Checked"); answer5.setChecked(answer5Checked); answer41Checked = savedInstanceState.getBoolean("answer41Checked"); answer41.setChecked(answer41Checked); answer42Checked = savedInstanceState.getBoolean("answer42Checked"); answer42.setChecked(answer42Checked); answer43Checked = savedInstanceState.getBoolean("answer43Checked"); answer43.setChecked(answer43Checked); answer44Checked = savedInstanceState.getBoolean("answer44Checked"); answer44.setChecked(answer44Checked); answer45Checked = savedInstanceState.getBoolean("answer45Checked"); answer45.setChecked(answer45Checked); isQuizFinished = savedInstanceState.getBoolean("isQuizFinished"); isQ1Correct = savedInstanceState.getBoolean("isQ1Correct"); isQ2Correct = savedInstanceState.getBoolean("isQ2Correct"); isQ3Correct = savedInstanceState.getBoolean("isQ3Correct"); isQ4Correct = savedInstanceState.getBoolean("isQ4Correct"); isQ5Correct = savedInstanceState.getBoolean("isQ5Correct"); if (isQuizFinished) { setCorrectAnswerColors(); } }
现在测试一下,旋转屏幕后用户的选择会完全保留,且如果已经完成测验,正确答案的绿色也会正常显示啦。
内容的提问来源于stack exchange,提问作者Cansu Yeksan
相关产品推荐
相关产品推荐

