通过方向更改维护进度条可见性

时间:2013-08-21 10:07:57

标签: android bundle android-progressbar

我在xml中定义了一个进度条(swirly waiting style):

<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的新方向中重新创建。所以我认为android保存的默认Bundle不包括对ProgressBar View对象所做的任何更改吗?

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

由于

更新:

以下提供的解决方案均有效。我决定选择将android:configChanges="orientation|screenSize"放入清单xml文件中。但是,文档说明此方法应仅用作最后手段。我的活动相当简单,因此清单xml方法减少了主活动所需的代码量,即没有onRestoreInstanceState方法。我认为如果你的活动更复杂,你可能想要使用后一种方法明确定义任何状态变化。

3 个答案:

答案 0 :(得分:7)

  

所以我认为默认的Bundle由android保存   不包括对ProgressBar View对象所做的任何更改?

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

  

[是]说恢复正确的唯一方法是正确的   方向更改后ProgressBar的可见性是保存a   通过重写方法标记(例如boolean pbState = false / true)   onSaveInstanceState并在onRestoreInstanceState中检查此标志   并相应地设置可见性?

绝对。关于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时,请将progressBarIsShowing设为true。当您解雇progressBar时,请切换它。

覆盖onSaveInstanceState(Bundle)

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

注意:检查用户何时浏览您的活动(通过按下主页按钮等)。如果用户在BadTokenException显示progressBar,则可能会获得{{1}}。

答案 1 :(得分:3)

您可以在清单中的活动代码中使用以下行。

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

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

答案 2 :(得分:0)

使用android:configChanges是不好的做法,因为它可能使您陷入更糟糕的困境。

在变量onSaveInstanceState上保存变量对我也不起作用,因为在活动被销毁时您将无法获得更新。

我最终在一个片段中使用了一个ResultReceiver,而该片段不会被setRetainInstance(true)破坏。

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

也请在这里查看我的答案:https://stackoverflow.com/a/54334864/6747171