Проблема при переключении раскладок из портретного в ландшафтный режим - PullRequest
2 голосов
/ 27 июля 2011

У меня есть два макета, один для портрета, другой для пейзажа.Для портрета он находится в папке layout, а для ландшафта - в папке 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, но портрет имеет.Если действие перезапускается (что меня устраивает) каждый раз, когда я меняю режим экрана, не должен ли он автоматически загружать соответствующие макеты?Буду признателен за любую помощь в этом.Спасибо.

ОБНОВЛЕНИЕ: 14:00

Я добавил код, но он все равно выдает ту же ошибку.Ошибка возникает из-за преобразования линейного макета в относительный макет, и вот в чем проблема.Макет портрета ("main.xml") находится в папке по умолчанию "layout".Этот макет имеет относительный макет («rlmain»).Компоновка ландшафта ("main.xml") находится в папке layout-land.Этот main.xml имеет различные спецификации пользовательского интерфейса и имеет линейную структуру.По умолчанию я загружаюсь в портретном режиме, где он загружается нормально, и я нажимаю Ctrl + F11, чтобы изменить его на альбомную, макет из папки layout-land загружается нормально.Затем я снова нажимаю Ctrl + F11, чтобы изменить его на Portrait, где файл main.xml из папки макета по умолчанию должен быть загружен, но не загружается, поэтому я получаю исключение для регистра.

Ответы [ 3 ]

1 голос
/ 27 июля 2011

Кажется, что вы пытаетесь привести LinearLayout к RelativeLayout, но это не имеет особого смысла, так как изначально он работает в портретном режиме. Это может быть проблемой с вашим оператором if в onCreate (). Возможно, что ваша функция loadMBIIntoView () вызывается, когда этого не должно быть, вызывая ошибку.

Вы проверяете для deviceRotation == 1, но это ловит только случай, когда устройство поворачивается на 90 градусов, игнорируя случай, когда оно поворачивается на 270 градусов.

Попробуйте вместо этого и посмотрите, изменится ли что-нибудь:

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

Surface.ROTATION_90 - это предопределенная константа, равная 1, а Surface.ROTATION_270 - 3.

EDIT:

Я все еще думаю, что это проблема с вашим устройством. Ctrl + F11 переходит к «предыдущей ориентации макета», а Ctrl + F12 переходит к «следующей ориентации макета», как описано здесь . Поэтому, когда вы дважды нажимаете F11, вы не возвращаетесь к исходной ориентации. Вы переходите в перевернутый портретный режим.

Попробуйте нажать F11 в первый раз, а затем F12 во второй раз, чтобы эмулятор действительно вернулся в свое истинное исходное состояние и посмотрите, не вызывает ли это по-прежнему ошибку.

РЕДАКТИРОВАНИЕ № 2:

Кажется, это проблема (возможно, ошибка) с вращением эмулятора. Подобный вопрос может быть найден здесь .

По сути, эмулятор выполняет дополнительные вызовы в течение жизненного цикла, а не реальные устройства. Предположительно, он имитирует вращение путем открытия клавиатуры вместо того, чтобы через акселерометр, как это делает реальное устройство.

Если вы можете, я бы протестировал ваш код на реальном устройстве, чтобы убедиться, что это законная проблема. Сейчас кажется, что это проблема с эмулятором, и вы должны ее игнорировать.

0 голосов
/ 21 июля 2015

Добавьте эти строки AndroidManifest.xml в свою деятельность, для которой вы хотите задать ориентацию.

android: configChanges = "direction | keyboardHidden | screenSize"

В коде используйте эти строки для изменения ориентации

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

Также следует помнить, чтобы установить ориентацию после <"setContentView"> как

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

0 голосов
/ 11 ноября 2011

Я тоже сталкивался с такой же проблемой.Это решено.Основная проблема в том, что при переключении с пейзажа на портрет активность не обновляется.Вы можете сделать одну вещь, переопределить onConfigurationChanged и реализовать следующим образом.Это освежит активность.

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

}

Это поможет вам.Пожалуйста, ответьте, если ваша проблема будет решена.

...