Android:onRetainNonConfigurationInstance()和方向更改具有不同的布局

时间:2011-01-27 19:48:02

标签: android android-layout screen-orientation

我有一个活动应该有两个相当不同的布局,具体取决于用户是以横向还是纵向模式保存它。

在onRetainNonConfigurationInstance()中,我存储了大量信息并将其提取到onCreate()中(如果存在),以恢复用户数据。

我有一种方法可以确定手机当前处于纵向还是横向模式 - 如果getWindowManager()。getDefaultDisplay()。getWidth()大于getWindowManager()。getDefaultDisplay()。getHeight(),则它是在风景中。

在我的纵向布局xml文件中,我有一些图像视图,这些视图在横向布局xml文件中不存在。在onCreate()中,我检查我们是否处于肖像状态,然后初始化并修改它们(如果是这样)。如果我们处于横向模式,我不会。

这一切都适用于从纵向切换到横向,但是当切换回肖像时,我的代码仅针对纵向模式执行会产生空指针异常 - 它无法找到视图元素。

堆栈追踪:

E/AndroidRuntime( 4800): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.apps.hyperview/com.apps.hyperview.PopUp}: java.lang.NullPointerException
E/AndroidRuntime( 4800):        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2268)
E/AndroidRuntime( 4800):        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2284)
E/AndroidRuntime( 4800):        at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3278)
E/AndroidRuntime( 4800):        at android.app.ActivityThread.access$1900(ActivityThread.java:112)
E/AndroidRuntime( 4800):        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
E/AndroidRuntime( 4800):        at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 4800):        at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime( 4800):        at android.app.ActivityThread.main(ActivityThread.java:3948)
E/AndroidRuntime( 4800):        at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 4800):        at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime( 4800):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:782)
E/AndroidRuntime( 4800):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:540)
E/AndroidRuntime( 4800):        at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime( 4800): Caused by: java.lang.NullPointerException
E/AndroidRuntime( 4800):        at com.apps.hyperview.PopUp.onCreate(PopUp.java:147)
E/AndroidRuntime( 4800):        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
E/AndroidRuntime( 4800):        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2231)

有没有人有任何想法我做错了什么?

谢谢! r3mo

修改

Popup.java部分导致问题:

// Check orientation. If we're in portrait...
if( isInPortrait() )
{
        spacer_above = (ImageView) findViewById(R.id.image_display_popup_spacer_above);
        spacer_above.setVisibility(View.INVISIBLE);    // THIS IS CAUSING THE NULLPOINTER
        spacer_below = (ImageView) findViewById(R.id.image_display_popup_spacer_below);
        spacer_below.setVisibility(View.INVISIBLE);
}
else;

布局文件的纵向版本包含这些“垫片”,但横向版本不包含这些“垫片”。这是使用onRetainNonConfigurationInstance()时如何更改方向和处理不同的布局?从纵向到横向,代码都可以正常工作,但是当回到肖像时,我得到了NullPointerException。

编辑2:

isInPortrait()似乎工作正常 - 但我会改变它。我不只是让视图不可见的原因是布局的结构在景观上有很大的不同。显然,这种横向布局工作正常 - 从纵向到横向然后再回到肖像时会出现错误。

感谢所有帮助!

编辑3:

我现在改变了我的方式,在layout-port /和layout-land /中使用相同的布局文件,并在View.GONE中创建我不想要的视图元素。获得关于这个问题的输入肯定是好的 - 看起来像android的一个非常强大的功能是能够为景观和肖像提供完全不同的布局。

谢谢!

1 个答案:

答案 0 :(得分:0)

您可以将纵向布局放在res / layout-port中,res / layout-land中布局的横向版本,以及res / layout中的默认(对于方形屏幕,我猜)。系统自动(并可靠地)确定要使用的布局版本。你有没有这样做的原因?