Не перезавантажуйте програму при зміні орієнтації


152

Мені просто не потрібно нічого міняти при поверненні екрана. Мій додаток відображає випадкове зображення під час першого завантаження, а обертання пристрою не повинно вибирати інше випадкове зображення. Як я можу (просто) змусити цю поведінку припинити?


1
Також можна заблокувати (і, можливо, розблокувати) орієнтацію екрана від коду. Просто зателефонуйте Screen.lockOrientation(this)з github.com/delight-im/Android-BaseLib/blob/master/Source/src/im / ... для цього. Це дозволяє розблокувати те, що маніфест не робить.
каре

@Escobar Ceaser Яке правильне рішення цього питання. Навіть у мене є однакові вимоги.
Прабс

Я хотів би це зробити програмно в коді.
pollaris

Відповіді:


249

Зазвичай це три способи:

  1. З деяких запропонованих відповідей ви можете розрізнити випадки вашої діяльності, створеної вперше та відновленої з неї savedInstanceState. Це робиться шляхом переосмислення onSaveInstanceStateта перевірки параметра onCreate.

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

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

Особисто я б пішов (3). Звичайно, якщо заблокувати додаток до однієї з орієнтацій з вами добре, ви також можете перейти з (2).


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
Дон

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()викликається. Це дозволить зберегти все, що є на екрані (тобто веб-сторінку в Webview), коли орієнтація зміниться.

Дізналися про це з цього веб-сайту: http://developer.android.com/guide/topics/manifest/activity-element.html

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

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


2
Дякую ... його робота після додавання "screenSize" з "орієнтацією"
Pratik Butani

Працює в android 4.2.1 Samsung Galaxy Nexus! android:configChanges="orientation|screenSize"
Вінсент Дукастель

Дивовижний. Я працюю над кодом стільки годин, щоб вирішити проблему, яку я мав із перезавантаженням діяльності та відео, починаючи з початку. І тут було рішення! ++++ 1
Матіас Асберг

6
Погана практика? Pfft, люди в реальному житті мають терміни, і якщо це працює, то воно працює;)
Kacy

Якщо це погана практика, то чому вона отримала стільки результатів ??
Гострий край

26

Вам просто потрібно перейти до AndroidManifest.xmlміток ізсередини чи всередині вашої діяльності. Ви повинні ввести цей рядок коду так, як хтось там сказав:

android:configChanges="orientation|screenSize"

Отже, у вас вийде щось подібне:

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

Сподіваюся, це працює!


це не завантажує мій макет-макет. :( не працював у мене
piyush poriya

16
<activity android:name="com.example.abc" 
 android:configChanges="orientation|screenSize"></activity>

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

Отже, активність не перезапуститься при зміні орієнтації.


Це працює. Але коли я використовую окремий макет для кожної орієнтації layout.xml та layout-land.xml. його застосований ландшафтний план для обох орієнтацій. Якщо я використовую лише "орієнтацію", це дає те, що я очікую, але перезавантажую. Чи можете ви допомогти у цьому?
Karthikeyan Ve

1
@KarthikeyanVe Це питання, коли ви намагаєтеся обдурити. Ви повинні перезавантажити вашу активність в макет зміни. Вперед і просто використовуйте реальне рішення, яке використовує onSaveInstanceState()і onCreate().
Марк Плано-Лесей

@ MarcPlano-Lesay, і як я можу це зробити?
Ахсан

@Weaboo власне рішення пов’язане у питанні: developer.android.com/guide/topics/resources/…
Марк Плано-Лесей

@ MarcPlano-Lesay У мене є окремий макет для портретного та ландшафтного режиму, якщо я відкриваю свою програму в ландшафтному або портретному режимі, вона працює добре, але коли я намагаюся змінити орієнтацію на час виконання, вона закриває додаток, проте коли я входжу в свій додаток а потім перейдіть до MainActivity і спробуйте змінити орієнтацію, вона перезавантажить цю діяльність і працює добре. Тепер питання, чому? Чи є логічна помилка в моєму коді? Idk, але я кілька разів намагався налагоджувати додаток, і нічого не можу знайти. Більше того, я не хочу перезапустити свою діяльність, чому ми не можемо просто адаптувати відповідний макет, коли зміниться конфігурація?
Ахсан

10

З мого досвіду, що насправді краще просто правильно впоратися зі змінами орієнтації, а не намагатися впоратись із поведінкою, що не використовується за замовчуванням.

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


№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

    }
}


3

Просто додайте це до свого AndroidManifest.xml

<activity android:screenOrientation="landscape">

Я маю на увазі, є тег активності, додайте це як інший параметр. Якщо вам потрібна орієнтація на портрет, змініть пейзаж на портрет. Сподіваюся, це допомагає.


я не шукаю, щоб забрати можливість обертання екрана. Я просто не хочу, щоб мій додаток перезавантажився ... як я вже згадував.
Джиммі Д

ps ... це все одно не працює. він просто змушує додаток відображатися в певній орієнтації. обертання екрана все ще перезавантажує активність
Джиммі Д

3

У файлі manifiest додайте до кожної дії це. Це допоможе

android:configChanges = "orientation|keyboard|keyboardHidden|screenLayout|screenSize"

screenLayout працював на мене, заважав оновити під час зміни розміру програми для splitscreen на 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.


насправді ви повинні зробити це методом onSaveInstanceState ()
Віллі Менцель,



-1

Я не знаю, чи найкраще рішення, але я описую його тут:

Перш за все, вам потрібен сертифікат з вашим класом Застосування вашої програми є в вашому маніфесті цього:

<application
    android:name=".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);
}

Я не знаю, чи це найелегантніше і найкрасивіше рішення, але принаймні тут воно функціональне :)


-2

Додайте цей код після onCreateметоду у вашій діяльності, що міститьWebView

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

@Override
protected void onRestoreInstanceState(Bundle state) {
    super.onRestoreInstanceState(state);    
}

1
Як би це працювало? Хіба ви просто не говорите щось явно під час виконання, що б інакше було зроблено за замовчуванням?
Даніельсон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.