Не перезагружать приложение при изменении ориентации

152

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

Джимми Д
источник
1
Также возможно заблокировать (и, возможно, разблокировать) ориентацию экрана из кода. Просто позвоните Screen.lockOrientation(this)с github.com/delight-im/Android-BaseLib/blob/master/Source/src/im/… для этого. Это позволяет разблокировать, что не манифест.
caw
@Escobar Ceaser Как правильно решить этот вопрос. Даже у меня такое же требование.
Прабс
Я хотел бы сделать это программно в коде.
Pollaris

Ответы:

249

Как правило, есть три способа сделать это:

  1. Как показывают некоторые ответы, вы можете различить случаи, когда ваша деятельность была создана впервые и восстановлена ​​из savedInstanceState. Это делается путем переопределения onSaveInstanceStateи проверки параметра onCreate.

  2. Вы можете заблокировать действие в одной ориентации, добавив android:screenOrientation="portrait"(или "landscape") <activity>в свой манифест.

  3. Вы можете сказать системе, что вы хотели обрабатывать изменения экрана для себя, указав android:configChanges="orientation|screenSize"в <activity>теге. Таким образом, действие не будет воссоздано, но вместо этого получит обратный вызов (который вы можете игнорировать, так как он бесполезен для вас).

Лично я бы пошел с (3). Конечно, если вам подходит привязка приложения к одной из ориентаций, вы также можете использовать (2).

Xion
источник
13
Так что для # 3 вы говорите, что все, что мне нужно сделать, это добавить эту строку в мой манифест? Потому что это не работает.
Джимми Д
2
# 3 Пожалуйста, проверьте на stackoverflow.com/questions/456211/…
Yeo
16
@EscobarCeaser, для Android 3.2 и выше вам нуженandroid:configChanges="orientation|screenSize"
Pacerier
9
android:configChanges="orientation|screenSize"работает для меня. Спасибо @Pacerier
Дон Larynx
1
пожалуйста, обновите ваш вариант ответа № 3 android:configChanges="orientation|screenSize"значением API> = 13, потому что многие люди считают ваш ответ основным!
Radistao
215

Ответ Xion был близок, но # 3 ( android:configChanes="orientation") не сработает, если приложение не имеет уровня API 12 или ниже.

На уровне API 13 или выше размер экрана изменяется при изменении ориентации, поэтому это все равно приводит к тому, что действие изменяется и запускается при изменении ориентации.

Просто добавьте атрибут «screenSize», как я сделал ниже:

<activity
    android:name=".YourActivityName"
    android:configChanges="orientation|screenSize">
</activity>

Теперь, когда вы меняете ориентацию (и размер экрана меняется), действие сохраняет свое состояние и onConfigurationChanged()вызывается. Это сохранит все, что находится на экране (т.е. веб-страницу в веб-просмотре), когда ориентация изменится.

Узнал об этом с этого сайта: http://developer.android.com/guide/topics/manifest/activity-element.html

Кроме того, это явно плохая практика, поэтому прочитайте ссылку ниже об обработке изменений времени выполнения:

http://developer.android.com/guide/topics/resources/runtime-changes.html

Корбин
источник
2
Спасибо ... его работа после добавления "screenSize" с "ориентацией"
Пратик Бутани
Работает в Samsung Galaxy Nexus Android 4.2.1! android:configChanges="orientation|screenSize"
Винсент Дюкастель
Удивительный. Я столько часов работал над кодом, чтобы решить проблему с перезагрузкой активности и видео с самого начала. И здесь было решение! ++++ 1
Матиас Асберг
6
Плохая практика? Пфф, у реальных людей есть крайние сроки, и если это работает, это работает;)
Кейси
Если это плохая практика, то почему она получила столько голосов ??
Sharp Edge
26

Вам просто нужно перейти к AndroidManifest.xmlметкам и внутри или в ярлыках ваших действий, вы должны ввести эту строку кода, как кто-то там сказал:

android:configChanges="orientation|screenSize"

Итак, у вас будет что-то вроде этого:

<activity android:name="ActivityMenu"
android:configChanges="orientation|screenSize">
</activity>

Надеюсь, что это работает!

Жозуэ Роча
источник
его не загружается мой макет земли. :( у меня не сработало
пиюш пория
16
<activity android:name="com.example.abc" 
 android:configChanges="orientation|screenSize"></activity>

Просто добавьте android:configChanges="orientation|screenSize"вкладку активности файла манифеста.

Таким образом, активность не будет перезапущена при изменении ориентации.

Айяз Пармар
источник
Это работает. Но когда я использую отдельный макет для каждой ориентации layout.xml и layout-land.xml. его применение ландшафтного расположения для обеих ориентаций. Если я использую только «ориентацию», это дает то, что я ожидаю, но перезагрузка. Не могли бы вы помочь в этом?
Картикеян Ве
1
@KarthikeyanVe Это проблема, когда вы пытаетесь обмануть. Вы должны перезагрузить вашу активность в макет изменения. Идите вперед и просто используйте реальное решение, которое использует onSaveInstanceState()и onCreate().
Марк Плано-Лесай,
@ MarcPlano-Lesay, и как мне это сделать?
Ахсан
@Weaboo фактическое решение связано в вопросе: developer.android.com/guide/topics/resources/…
Марк Плано-Лесей
@ MarcPlano-Lesay У меня есть отдельный макет для портретного и ландшафтного режима, если я открываю свое приложение в альбомном или портретном режиме, оно работает нормально, но всякий раз, когда я пытаюсь изменить ориентацию во время выполнения, оно закрывает мое приложение, однако при входе в мое приложение а затем перейдите к MainActivity и попробуйте изменить ориентацию, он перезагружает эту активность и работает нормально. Теперь вопрос почему? Есть ли логическая ошибка в моем коде? Да, но я несколько раз пытался отладить приложение и ничего не могу найти. Более того, я не хочу возобновлять свою деятельность, почему мы не можем просто адаптировать соответствующий макет при изменении конфигурации?
Асан
10

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

Вы должны сохранить изображение, которое отображается в данный момент, onSaveInstanceState()и правильно восстановить его при onCreate()повторном запуске приложения .

DMON
источник
№ 3 - совершенно правильное решение. Это точный инструмент, созданный для решения этой проблемы. Почему вы говорите, что это рожок для обуви?
Pacerier
1
@Pacerier Просто прочитайте документы. «Примечание: android:configChangesследует избегать использования и использовать его только в качестве крайней меры. Пожалуйста, прочтите Обработка изменений времени выполнения для получения дополнительной информации о том, как правильно обрабатывать перезапуск из-за изменения конфигурации».
Марк Плано-Лесай,
Не могли бы вы выложить пример сохранения и восстановления.
Pollaris
6

Это решение на сегодняшний день является лучшим рабочим. В вашем файле манифеста добавить

<activity
    android:configChanges="keyboardHidden|orientation|screenSize"
    android:name="your activity name"
    android:label="@string/app_name" 
    android:screenOrientation="landscape">
  </activity

И в вашем классе деятельности добавьте следующий код

@Override
public void onConfigurationChanged(Configuration newConfig) 
{
    super.onConfigurationChanged(newConfig);
    if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        //your code
    } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
  //your code

    }
}
Радж
источник
4

добавить android:configChanges="keyboardHidden|orientation|screenSize"для всех тегов активности приложения в манифесте.

Оубайда АльКураан
источник
3

Просто добавьте это к вашему AndroidManifest.xml

<activity android:screenOrientation="landscape">

Я имею в виду, есть тег активности, добавьте это в качестве другого параметра. Если вам нужна книжная ориентация, измените альбомную на портретную. Надеюсь это поможет.

Егор
источник
Я не хочу лишать меня возможности поворачивать экран. я просто не хочу, чтобы мое приложение перезагрузилось ... как я уже говорил.
Джимми Д
PS ... это не работает в любом случае. оно просто заставляет приложение отображаться в определенной ориентации. вращение экрана по-прежнему перезагружает активность
Джимми Д
3

В файле манифеста добавить к каждому виду деятельности это. Это поможет

android:configChanges = "orientation|keyboard|keyboardHidden|screenLayout|screenSize"
Евгений Кононов
источник
У меня работал screenLayout, предотвращал обновление при изменении размера приложения для разделенного экрана на Android
Terren
2

Все вышеперечисленные ответы не работают для меня. Итак, я исправил, упомянув как labelс screenOrientationниже. Теперь все нормально

<activity android:name=".activity.VideoWebViewActivity"
        android:label="@string/app_name"
        android:configChanges="orientation|screenSize"/>
Бах
источник
1

Сохраните детали изображения в вашем onPause()или onStop()и используйте его в onCreate(Bundle savedInstanceState)для восстановления изображения.

РЕДАКТИРОВАТЬ:

Более подробная информация о реальном процессе подробно описана здесь http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle, поскольку в Honeycomb он отличается от предыдущих версий Android.

techiServices
источник
на самом деле вы должны сделать это в методе onSaveInstanceState ()
Вилли Ментцель,
1

просто используйте: android:configChanges="keyboardHidden|orientation"

Масуд Банимахд
источник
1

Как отметил Пейсер,

android:configChanges="orientation|screenSize"

Донская гортань
источник
-1

Я не знаю, если это лучшее решение, но я опишу его здесь:

Прежде всего, вам нужен сертификат с вашим классом Приложение вашего приложения в вашем манифесте этого:

<application
    android:name=".App"
    ...

Во-вторых, в моем классе App я сделал так:

public class App extends Application {
    public static boolean isOrientationChanged = false;

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onConfigurationChanged(@NotNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE ||
                newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
            isOrientationChanged = true;
        }
    }

}

В-третьих, вам нужно установить флаг «Изменение ориентации», в моем случае я всегда устанавливаю его при вызове предыдущего действия в навигации приложения, поэтому вызывать его нужно только один раз, когда создается последнее действие.

isOrientationChanged = false;

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

По сути, мне приходилось использовать его всякий раз, когда я делал асинхронный запрос на модификацию, который он вызывал каждый раз, когда менялась ориентация, постоянно сбой приложения:

if (!isOrientationChanged) {
    presenter.retrieveAddress(this, idClient, TYPE_ADDRESS);
}

Не знаю, самое ли это элегантное и красивое решение, но, по крайней мере, здесь оно функционально :)

michel566
источник
-2

Добавьте этот код после onCreateметода, в вашей деятельности, содержащейWebView

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);    
}

@Override
protected void onRestoreInstanceState(Bundle state) {
    super.onRestoreInstanceState(state);    
}
Амир Аслам
источник
1
Как это будет работать? Разве вы просто не говорите что-то явно среде выполнения, что в противном случае было бы сделано по умолчанию?
Дэниелсон,