Android横竖屏旋转时保持TextView问题状态的解决方案求助
解决横竖屏旋转时问答内容重置的问题
嘿,我看了你的代码,确实是onSaveInstanceState的实现出了问题,另外也给你讲讲用ViewModel来搞定这个需求的更简便方法,一步一步来:
一、先修复onSaveInstanceState的错误
你现在的代码里,状态保存和恢复的逻辑有两个明显的问题:
- Key不匹配:保存状态时用的是
"count"作为key,但恢复的时候却去取"Questions",这肯定读不到数据啊! - 保存的数据不对:你存的是
questions[count](也就是字符串资源的ID),但我们真正需要保存的是当前问题的索引count,这样恢复的时候才能找到对应的问题。
修正后的完整Activity代码:
public class AnotherQuestionActivity extends AppCompatActivity { private TextView mTextViewCount; private int [] questions= {R.string.Q1,R.string.Q2,R.string.Q3,R.string.Q4,R.string.Q5}; private int count=0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_question); mTextViewCount = findViewById(R.id.Question_text_view); Button buttonDecrement = findViewById(R.id.button); Button buttonIncrement = findViewById(R.id.button3); buttonDecrement.setOnClickListener(v -> yesbutton()); buttonIncrement.setOnClickListener(v -> nobutton()); // 恢复之前保存的count值 if (savedInstanceState != null) { count = savedInstanceState.getInt("count"); } // 不管是第一次启动还是恢复状态,都要设置当前显示的问题 mTextViewCount.setText(questions[count]); } private void yesbutton() { // 加个判断防止数组越界,避免点到最后一个问题时崩溃 if(count < questions.length -1){ count++; mTextViewCount.setText(questions[count]); } } private void nobutton() { if(count < questions.length -1){ count++; mTextViewCount.setText(questions[count]); } } @Override protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); // 保存当前的问题索引count,而不是资源ID outState.putInt("count", count); } }
二、用ViewModel实现更省心的状态保存
如果你觉得手动处理onSaveInstanceState太麻烦,ViewModel绝对是更好的选择——它是Jetpack专门用来在配置变化(比如横竖屏旋转)时保存数据的组件,完全不用管状态的保存和恢复,代码更简洁可靠。
第一步:创建ViewModel类
这个类很简单,就是用来存我们需要保留的count变量:
import androidx.lifecycle.ViewModel; public class QuestionViewModel extends ViewModel { // 这里的count会在配置变化时被保留 public int count = 0; }
第二步:修改Activity代码使用ViewModel
import androidx.lifecycle.ViewModelProvider; public class AnotherQuestionActivity extends AppCompatActivity { private TextView mTextViewCount; private int [] questions= {R.string.Q1,R.string.Q2,R.string.Q3,R.string.Q4,R.string.Q5}; // 声明ViewModel实例 private QuestionViewModel questionViewModel; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_question); // 获取ViewModel实例,横竖屏旋转时这个实例不会被销毁 questionViewModel = new ViewModelProvider(this).get(QuestionViewModel.class); mTextViewCount = findViewById(R.id.Question_text_view); Button buttonDecrement = findViewById(R.id.button); Button buttonIncrement = findViewById(R.id.button3); buttonDecrement.setOnClickListener(v -> yesbutton()); buttonIncrement.setOnClickListener(v -> nobutton()); // 直接用ViewModel里的count来设置当前问题 mTextViewCount.setText(questions[questionViewModel.count]); } private void yesbutton() { if(questionViewModel.count < questions.length -1){ questionViewModel.count++; mTextViewCount.setText(questions[questionViewModel.count]); } } private void nobutton() { if(questionViewModel.count < questions.length -1){ questionViewModel.count++; mTextViewCount.setText(questions[questionViewModel.count]); } } // 这里完全不需要重写onSaveInstanceState了!ViewModel会自动搞定状态保存 }
另外提一句,你的横竖屏布局XML里关键控件的ID都是一致的,系统会自动根据屏幕方向加载对应的布局,这部分没问题,不用改。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

