2

我在 xml 中定义了一个进度条(漩涡等待风格):

<ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="@android:style/Widget.Holo.ProgressBar.Large"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:id="@+id/progress"
        />

onCreate我在活动的方法中隐藏了它的可见性,使用,

progressBar.setVisibility(View.GONE);

onClick并使用在按钮的事件上启动它

progressBar.setVisibility(View.VISIBLE);

现在,如果我改变屏幕方向,进度条就会消失。我了解活动在方向更改时被销毁并重新创建,并且活动的状态是从保存的新方向重新创建的Bundle savedInstanceState。那么我认为Bundleandroid保存的默认值不包括对ProgressBarView对象所做的任何更改是否正确?

如果是这种情况,是否正确地说在方向更改后恢复正确可见性的唯一方法是通过覆盖方法并检查该标志并相应地设置可见性ProgressBar来保存标志(例如) ?或者,我是否遗漏了一些关于保存视图对象状态的非常明显的东西。boolean pbState = false/trueonSaveInstanceStateonRestoreInstanceState

谢谢

更新:

下面提供的两种解决方案都有效。我决定选择放入android:configChanges="orientation|screenSize"清单 xml 文件。但是,文档指出,这种方法只能作为最后的手段使用。我的活动相当简单,因此清单 xml 方法减少了主要活动中所需的代码量,即没有onRestoreInstanceState方法。我想如果您的活动更复杂,您可能希望使用后一种方法明确定义任何状态更改。

4

3 回答 3

7

那么我认为android保存的默认Bundle不包括对ProgressBar View对象所做的任何更改是否正确?

你说的对。Android 不会保存 的状态progressBar,或任何其他小部件的状态。

[是否]正确地说,在方向更改后恢复 ProgressBar 正确可见性的唯一方法是通过覆盖方法 onSaveInstanceState 并在 onRestoreInstanceState 中检查此标志并设置来保存标志(例如布尔 pbState = false/true)相应的能见度?

绝对地。关于onRestoreInstanceState(Bundle):您可以不覆盖此方法。要确认方向更改,请检查savedInstanceState ==> Bundle passed to onCreate(Bundle)反对null。如果发生方向更改,savedInstanceState则不会为空。在活动开始时,savedInstanceState将是null。以下代码(基本上是您提出的)应该可以完成这项工作:

声明一个全局布尔变量:

boolean progressBarIsShowing;

在你的onCreate(Bundle)

// savedInstanceState != null ===>>> possible orientation change 
if (savedInstanceState != null && savedInstanceState.contains("progressbarIsShowing")) {

    // If `progressBarIsShowing` was stored in bundle, `progressBar` was showing
    progressBar.setVisibility(View.VISIBLE);

} else {

    // Either the activity was just created (not recreated), or `progressBar` wasn't showing
    progressBar.setVisibility(View.GONE);

}

每当您显示progressBar时,设置progressBarIsShowingtrue。并在您关闭时切换它progressBar

覆盖onSaveInstanceState(Bundle)

if (progressBarIsShowing) {
    outState.putBoolean("progressBarIsShowing", progressBarIsShowing);
}

注意:检查用户何时离开您的活动(通过按下主页按钮等)。当用户这样做时,您可能会看到BadTokenExceptionif正在显示。progressBar

于 2013-08-21T10:17:13.763 回答
3

您在清单中的活动标记内使用以下行。

<activity android:name="your activity"
        android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>

以上android:configChanges="orientation"将在配置更改时保持应用程序的状态。

于 2013-08-21T10:14:19.413 回答
0

使用android:configChanges是不好的做法,因为它可能会给你带来更糟糕的麻烦。

还保存一个变量onSaveInstanceState对我不起作用,因为在 Activity 被销毁时你不会得到更新。

我最终在 Fragment 中使用了一个 ResultReceiver,它不会被使用setRetainInstance(true).

关于这个问题的一篇好文章可以在这里找到: https ://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html

另请参阅我的答案:https ://stackoverflow.com/a/54334864/6747171

于 2019-01-23T20:41:11.000 回答