如何在Android中在运行时更改方向时保持弹出窗口打开?

7

我创建了一个弹出窗口,其中包含月视图以选择日期。当我更改方向时,由于Android重新加载整个活动,我的弹出窗口会消失。如何使其在运行时发生方向变化时仍然保持打开状态?


您可以阅读此链接:http://blog.doityourselfandroid.com/2010/11/14/handling-progress-dialogs-and-screen-orientation-changes/,该链接涉及处理进度对话框和屏幕方向更改的相关内容。 - Sergey Benner
4个回答

5
在您的AndroidManifest.xml中包含android:configChanges="orientation",以便在显示窗口的活动中处理方向更改。这样做告诉Android您将自行处理方向更改,并最终不会销毁您的活动并保持窗口显示。
如果您没有纵向和横向模式的不同布局,则此技术非常好。但是,如果您有不同的布局,则仍可以通过检测以下方向模式执行自定义布局实现:
@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    if(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)
        Log.i("orientation", "Orientation changed to: Landscape");
    else
        Log.i("orientation", "Orientation changed to: Portrait");
}

为了预览,请下载并安装此示例应用程序


1
你是否为纵向和横向方向拥有两种不同的布局?因为我刚刚在单个XML布局上测试了这个,它可以正常工作。 - waqaslam
很奇怪,因为我在单个布局上测试过它,而且它运行良好。请查看我的演示apk:http://www.2shared.com/file/LdtQTybl/HelloWorld.html - waqaslam
它甚至可以与PopupWindow一起使用。请查看我的新示例:http://speedy.sh/pan48/HelloWorld.apk - waqaslam
我正在使用Spinner和AutoCompleteTextView,它们使用PopupWindow。我的代码与开发者网站提供的示例一样简单。但是在清单文件中,我的Activity被定义为 android:configChanges="orientation"。我相信,您一定是在做其他错误的事情,这会导致屏幕方向变化时重新创建显示。 - waqaslam
嗯,很好,你解决了它。我建议你除了模拟器之外还要使用硬件(真实手机)设备。因为随着时间的推移,当你的应用程序变得更大时,模拟器会比真实手机慢。此外,还有许多其他好处。 - waqaslam

4
每当屏幕方向改变时,Android都会销毁你的活动(调用onDestroy())然后重新启动它(调用onCreate())。 一旦你的弹出窗口出现,就设置一个标志popup_open=1。你的弹出窗口自然会有一个关闭按钮。在此按钮的单击处理程序中将标志设置为0。然后你可以在方法onRestoreInstanceState()onCreate()中重新打开弹出窗口。在这里,你需要检查标志的状态。如果标志被设置为1,则呈现弹出窗口。因此,即使在弹出窗口出现时改变了屏幕方向,onRestoreInstanceState()将根据标志的状态知道该怎么做。 更多参考内容请查看:如何处理运行时更改

假设您的弹出窗口有一些按钮供用户关闭。在此按钮的单击处理程序中,您将使用 popup_open=0。在启动弹出窗口时立即设置 popup_open=1。因此,如果弹出窗口已打开并且方向发生更改,则标志不会被设置为 0,因此 onRestoreInstanceState() 应该可以解决所有问题。我将编辑我的答案以处理在弹出窗口中设置标志,而不是由 onSaveInstanceState 进行设置。 - Urban
是的,我想说的是你应该在包含弹出对象的 OnClick() 方法中设置标志。之前我建议在 onSaveInstanceState 中设置标志。 - Urban
我觉得你有点混淆了。为什么你要在onSaveInstance中进行检查呢?正如这个方法的名称所示,该方法是在销毁应用程序之前调用的(即在方向更改后立即调用,当Android即将重新启动您的应用程序时)。您应该在onRestoreInstanceState()onCreate()中检查值。请查看我答案中提供的链接。 - Urban
在onCreate中创建弹出窗口是完全可能的。你是否在onCreate中重新声明了所有对象?你必须在onCreate中重复整个弹出窗口创建过程。这可能会有所帮助:http://stackoverflow.com/questions/9044093/how-to-load-popup-window-on-android-application-startup-oncreate - Urban

1
将此属性添加到 manifest.xml 中的活动中。
android:configChanges="orientation|keyboard" 

应该这样就可以了。


有些人就是无法把手从踩按钮上拿开,如果我的回答是错误的,那么那个人能否解释一下为什么呢? - Arif Nadeem

0

显示弹出窗口

final View parent = findViewById(R.id.{parentId});
parent.post(new Runnable() {
    @Override
    public void run() {
        mPopup.showAtLocation(parent, ...);
    }
});

解决屏幕方向变化时未处理的异常


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