【问题标题】:Problem when switching layouts from portrait to landscape mode将布局从纵向模式切换到横向模式时出现问题
【发布时间】:2011-10-14 09:31:24
【问题描述】:

我有两种布局,一种用于纵向,一种用于横向。对于纵向,我将它放在布局文件夹下,对于横向,我将它放在 layout-land 文件夹下。两者具有相同的名称 main.xml。从纵向到横向的切换没有任何错误。同样,当我从横向切换到纵向时,由于某种原因它没有加载基于纵向的布局并且无法找到我定义的根布局。这是 Logcat 输出\

07-27 15:25:09.601: WARN/System.err(278): java.lang.ClassCastException:    android.widget.LinearLayout
07-27 15:25:10.230: WARN/System.err(278):     at  com.me2youmob.swagwrap.ChickenWrapActivity.loadMBIIntoView(ChickenWrapActivity.java:102)
07-27 15:25:10.230: WARN/System.err(278):     at com.me2youmob.swagwrap.ChickenWrapActivity.onCreate(ChickenWrapActivity.java:41)
07-27 15:25:10.230: WARN/System.err(278):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
07-27 15:25:10.250: WARN/System.err(278):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
07-27 15:25:10.250: WARN/System.err(278):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
07-27 15:25:10.250: WARN/System.err(278):     at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3815)
07-27 15:25:10.311: WARN/System.err(278):     at android.app.ActivityThread.access$2400(ActivityThread.java:125)
07-27 15:25:10.311: WARN/System.err(278):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2037)
07-27 15:25:10.311: WARN/System.err(278):     at android.os.Handler.dispatchMessage(Handler.java:99)
07-27 15:25:10.322: WARN/System.err(278):     at android.os.Looper.loop(Looper.java:123)
07-27 15:25:10.322: WARN/System.err(278):     at android.app.ActivityThread.main(ActivityThread.java:4627)
07-27 15:25:10.329: WARN/System.err(278):     at java.lang.reflect.Method.invokeNative(Native Method)
07-27 15:25:10.329: WARN/System.err(278):     at java.lang.reflect.Method.invoke(Method.java:521)
07-27 15:25:10.361: WARN/System.err(278):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
07-27 15:25:10.361: WARN/System.err(278):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
07-27 15:25:10.371: WARN/System.err(278):     at dalvik.system.NativeStart.main(Native Method)

onCreate 中的代码如下

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);        
    int deviceRotation = getWindowManager().getDefaultDisplay().getRotation();
    Utils.spPreferences = getSharedPreferences(Utils.PREFS_NAME, 0);
    if (deviceRotation == 1)
    {
        int imgID = Utils.getMbiIndex("mbiIndex");  
        int drawBgId = Utils.getMbiDrawIndex(imgID);
        try 
        {
            ImageView ivLandView = (ImageView) findViewById(R.id.ivLandMbi);
            ivLandView.setImageResource(drawBgId);
        } 
        catch (Exception e) 
        {
            e.printStackTrace();
        }                   
    }
    else
    {
        loadMBIIntoView();
        handleButtonClicks(); 
    }
}

错误发生在loadMBIIntoView方法上,代码如下

    public void loadMBIIntoView() 
{
    int imgID = Utils.getMbiIndex("mbiIndex");  
    int drawBgId = Utils.getMbiDrawIndex(imgID);
    try {
        RelativeLayout llMain = (RelativeLayout) findViewById(R.id.rlMain);
        Resources res = getResources();
        Drawable drawMbi = res.getDrawable(drawBgId);
        llMain.setBackgroundDrawable(drawMbi);          
    } catch (Exception e) {
        e.printStackTrace();
    }
}

横向布局本身没有 rlMain 布局,但纵向有。如果每次更改屏幕模式时都重新启动活动(这对我来说很好),它不应该自动加载适当的布局吗?我将不胜感激这方面的任何帮助。谢谢。

更新:下午 02:00

我添加了代码,但它仍然给出相同的错误。由于将线性布局转换为相对布局,因此会出现错误,这就是问题所在。纵向布局(“main.xml”)位于其默认的“布局”文件夹中。此布局具有相对布局(“rlmain”)。横向布局(“main.xml”)位于 layout-land 文件夹中。这个 main.xml 有不同的 UI 规范,并且具有线性布局。默认情况下,我以纵向模式加载,加载正常,然后按 Ctrl + F11 将其更改为横向,layout-land 文件夹中的布局加载正常。然后我再次按 Ctrl + F11 更改为 Portrait,默认布局文件夹中的 main.xml 应该已加载但未加载,这就是我收到案例异常的原因。

【问题讨论】:

  • 横向文件不包含rlMain? Android 会自动在 layout 和 layout-land 中的布局之间切换,但不会创建不存在的布局。如果 rlMain 不在横向文件中,findViewById(R.id.rlMain) 将返回 null 并且当您尝试使用它时会出现错误。
  • 是的,横向文件不包含 rlMain。我已经设置了约束,以便在激活横向模式时不会调用 rlMain。当我切换回纵向模式时出现错误,它应该加载纵向布局并且应该能够找到 rlMain。
  • 知道了。那么 ChickenWrapActivity 的第 102 行是什么?
  • 布局文件夹中是否有横向和纵向的默认布局,而不仅仅是 layout-portrait 和 layout-landscape?如果您可以包含给出错误发生的确切行的堆栈跟踪,这也会有所帮助。
  • @theisenp,第 102 行正在尝试获取 rlMain 实例 RelativeLayout llMain = (RelativeLayout) findViewById(R.id.rlMain);

标签: android android-layout android-linearlayout android-relativelayout


【解决方案1】:

您似乎正在尝试将 LinearLayout 转换为 RelativeLayout,但这没有多大意义,因为它最初在纵向模式下工作。不过,您在 onCreate() 中的 if 语句可能有问题。您的 loadMBIIntoView() 函数可能在不应该被调用时被调用,从而导致错误。

您测试 deviceRotation == 1,但这仅捕获设备旋转 90 度的情况,忽略设备旋转 270 度的情况。

试试这个,看看是否有任何变化:

if(deviceRotation == Surface.ROTATION_90 || deviceRotation == Surface.ROTATION_270)
{
    ...
}
else
{
    ...
}

Surface.ROTATION_90 是一个预定义的常数,等于 1,Surface.ROTATION_270 等于 3。

编辑:

我仍然认为您的 deviceRotation 有问题。 Ctrl + F11 转到“上一个布局方向”,而 Ctrl + F12 转到“下一个布局方向”,如here 所述。因此,当您按 F11 两次时,您不会返回到原始方向。您正在切换到颠倒的纵向模式。

尝试第一次按 F11,然后第二次按 F12,让模拟器真正回到原来的状态,看看是否仍然会导致错误。

编辑 #2:

这似乎是模拟器旋转的问题(possibly a bug)。 可以找到与此类似的问题here

本质上,模拟器会进行额外的生命周期调用,而真实设备不会。假设它通过opening the keyboard 模拟旋转,而不是像真实设备那样通过加速度计。

如果可以的话,我会在真实设备上测试你的代码,看看它是否是一个合法的问题。现在看来这只是模拟器的问题,您应该忽略它。

【讨论】:

  • 我无法输入整个内容,因此我在原始帖子中添加了更新。您对布局转换的想法是正确的,问题是在纵向模式下加载了错误的布局,我不确定为什么会这样。
  • 这工作:) 非常感谢。如果我按 Ctrl + F12 它正在工作但这是否意味着在手机上当设备倒置时,布局会崩溃?
  • 是的,当你把它倒过来时它仍然会崩溃。但现在我们知道该错误与旋转有关。您是否按照我的建议更新了 if 语句?
  • 是的,我确实更新了语句,如果我按三次 Ctrl + F11 会崩溃,但在按 Ctrl + F11 然后按 Ctrl + F12 再按 Ctrl + F11 时不会崩溃。
  • 谢谢@theisenp,我也会在设备上进行测试。再次感谢您抽出宝贵时间,感谢您:)
【解决方案2】:

我也遇到了同样的问题。它解决了。它的主要问题是当您从横向切换到纵向时,活动不刷新。您可以做一件事,覆盖 onConfigurationChanged 并像这样实现。它将刷新活动。

public void onConfigurationChanged(Configuration newConfig) {
    // TODO Auto-generated method stub
    super.onConfigurationChanged(newConfig);
    startActivity(getIntent());
    finish();

}

它会帮助你。如果您的问题得到解决,请回复。

【讨论】:

  • 如果您的意图真的是刷新/重新创建活动,那么为什么还要费心处理 onConfigurationChanged() 呢?只需从清单中的活动中取出 android:configChanges ,无论如何它都会自动重新创建您的活动。 ¯_(ツ)_/¯
【解决方案3】:

将这行 AndroidManifest.xml 添加到您要指定方向的活动中。

android:configChanges="orientation|keyboardHidden|screenSize"

在代码中使用这些行来改变方向

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

还要记住在 之后设置方向

setContentView(R.layout.main); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-02
    • 1970-01-01
    • 2012-03-05
    • 2014-05-11
    相关资源
    最近更新 更多