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


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.