Android 横竖屏切换时如何保存状态

40

我有一个Android应用程序,它记录了行驶距离、时间等状态。这些状态可以方便地存储在对象中,并在Android调用onDestroy()时将该对象的引用存储在Bundle中,以便在创建新的Activity时恢复状态。但是,屏幕上的一些按钮和EditText对象也具有我想要在屏幕旋转时保持不变的状态。例如,在onStart(Bundle savedBundle)中,我会调用:

_timerButton.setBackgroundColor(Color.GREEN);
_pauseButton.setBackgroundColor(Color.YELLOW);
_pauseButton.setEnabled(false);

在我的应用程序运行过程中,这些按钮的颜色/启用状态将会发生改变。有没有一种更方便的方法来保持用户界面元素(EditText、Button 对象等)的状态,而不必为每个按钮手动保存/恢复每个属性?手动管理屏幕方向之间的此类状态感觉非常笨拙。

感谢任何帮助。

2个回答

127

在 Manifest 文件中添加 android:configChanges

<activity name= ".MainActivity" 
 android:configChanges="orientation|screenSize"/>

默认情况下,更改方向会导致onCreate方法被再次调用并重新绘制视图,因此此功能无法正常工作。

但是,如果包括此参数,则框架将处理保留屏幕或布局的状态,如果更改了方向。

有关更多信息,请参阅以下官方文档:

Activity Lifecycle

处理配置更改


4
很好的回答,帮助我理解了“configChanges”。 - Naveed Ahmad
5
哇,真的是这么简单...把这行代码添加到我的清单文件中解决了我的问题。现在,在屏幕方向改变时似乎所有的状态都会持久化,而不需要手动在 Bundle 中保存状态。onCreate/onDestroy 在屏幕方向改变时也不再被调用。非常感谢! - Intervention
3
我对安卓系统很陌生,不觉得这么简单。有什么问题吗?为什么默认没有开启呢?肯定有什么缺点吧。。 - Izzy Rodriguez
8
问题在于,由于Activity的onCreate()方法不再被调用,因此任何在onCreate()中重要的调用都会被忽略,这使得为不同方向显示不同视图变得更加困难。 - mwieczorek
这个问题还存在吗?我正在使用Android Studio 3创建一个新的应用程序,但是在2017年2月发现EditTexts、SeekBars和Spinners上的值仍然保留,即使我为该活动提供了一个备用的layout-land布局资源。 - Andrew S
我遇到过的最好的答案。 - eli

29

为了保存变量或值,应使用 onSaveInstanceState(Bundle) 方法;当方向更改时,应使用 onRestoreInstanceState() 方法恢复值,但这并不常见。(onRestoreInstanceState() 在 onStart() 之后调用,而 onCreate() 在 onStart() 之前调用。) 使用 put 方法在 onSaveInstanceState() 中存储值。

protected void onSaveInstanceState(Bundle icicle) {
  super.onSaveInstanceState(icicle);
  icicle.putLong("param", value);
}

并在 onCreate() 方法中恢复这些值:

public void onCreate(Bundle icicle) {
  if (icicle != null){
    value = icicle.getLong("param");
  }
}

2
谢谢回复。实际上我在寻找一种方法,不必在onCreate和onSaveInstanceState中手动进行Bundle管理工作,这就是为什么我接受了ranjith的答案 - 但这对于这个问题来说肯定是很好的信息。 - Intervention

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接