我在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
方法。我认为如果你的活动更复杂,你可能想要使用后一种方法明确定义任何状态变化。
答案 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