Перезапуск активности при ротации Android - PullRequest
1307 голосов
/ 19 января 2009

В моем приложении для Android, когда я поворачиваю устройство (выдвигаю клавиатуру), мой Activity перезапускается (вызывается onCreate). Теперь, вероятно, так и должно быть, но я делаю много начальных настроек в методе onCreate, поэтому мне нужно либо:

  1. Поместите все начальные настройки в другую функцию, чтобы они не терялись при повороте устройства или
  2. Сделайте так, чтобы onCreate больше не вызывался, а раскладка просто настраивалась или
  3. Ограничьте приложение только портретом, чтобы onCreate не вызывался.

Ответы [ 31 ]

15 голосов
/ 21 августа 2014

Поместите код ниже внутри тега <activity> в Manifest.xml:

android:configChanges="screenLayout|screenSize|orientation"
14 голосов
/ 14 декабря 2015

Это очень просто, просто выполните следующие шаги:

<activity
    android:name=".Test"
    android:configChanges="orientation|screenSize"
    android:screenOrientation="landscape" >
</activity>

Это работает для меня:

Примечание: ориентация зависит от вашего требования

14 голосов
/ 23 июля 2014

Добавьте эту строку в манифест: -

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

и этот фрагмент к действию: -

@Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
    }
14 голосов
/ 01 февраля 2012
 onConfigurationChanged is called when the screen rotates. 
 (onCreate is no longer called when screen rotates due to manifest, see:  
 android:configChanges)

Какая часть манифеста говорит: «Не звоните onCreate()»?

Кроме того, Документы Google говорят, что следует избегать использования android:configChanges (кроме как в крайнем случае) .... Но тогда альтернативные методы, которые они предлагают, все DO используют android:configChanges.

По моему опыту, эмулятор ВСЕГДА вызывает onCreate() при вращении.
Но на 1-2 устройствах, на которых я запускаю один и тот же код ... нет. (Не уверен, почему будет какая-то разница.)

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

Изменения, которые необходимо внести в манифест Android:

android:configChanges="keyboardHidden|orientation" 

Дополнения, которые будут сделаны внутри деятельности:

public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }
}
12 голосов
/ 07 января 2016

Есть несколько способов сделать это:

Сохранить состояние активности

Вы можете сохранить состояние активности в onSaveInstanceState.

@Override
public void onSaveInstanceState(Bundle outState) {
    /*Save your data to be restored here
    Example : outState.putLong("time_state", time); , time is a long variable*/
    super.onSaveInstanceState(outState);
}

, а затем используйте bundle для восстановления состояния.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if(savedInstanceState!= null){
       /*When rotation occurs
        Example : time = savedInstanceState.getLong("time_state", 0); */
    } else {
      //When onCreate is called for the first time
    }
}

Ручка изменения ориентации самостоятельно

Другая альтернатива - справиться с изменениями ориентации самостоятельно. Но это не считается хорошей практикой.

Добавьте это в свой файл манифеста.

android:configChanges="keyboardHidden|orientation"

для Android 3.2 и более поздних версий:

android:configChanges="keyboardHidden|orientation|screenSize"

@Override
public void onConfigurationChanged(Configuration config) {
    super.onConfigurationChanged(config);

if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        //Handle rotation from landscape to portarit mode here
    } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){
        //Handle rotation from portrait to landscape mode here
    }
}

Ограничить вращение

Вы также можете ограничить свою деятельность портретным или ландшафтным режимом, чтобы избежать поворота.

Добавьте это в тег активности в файле манифеста:

        android:screenOrientation="portrait"

Или реализовать это программно в своей деятельности:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
10 голосов
/ 16 марта 2012

Несмотря на то, что это не «способ Android», я получил очень хорошие результаты, обрабатывая изменения ориентации самостоятельно и просто перемещая виджеты в пределах представления, чтобы принять во внимание измененную ориентацию. Это быстрее, чем любой другой подход, потому что ваши представления не должны быть сохранены и восстановлены. Это также обеспечивает более удобную работу для пользователя, поскольку видоизмененные виджеты - это точно такие же виджеты, только что перемещенные и / или измененные. Таким образом можно сохранить не только состояние модели, но и состояние просмотра.

RelativeLayout иногда может быть хорошим выбором для представления, которое время от времени должно переориентироваться. Вы просто предоставляете набор параметров портретного макета и набор параметров ландшафтного макета с различными правилами относительного позиционирования для каждого дочернего виджета. Затем в своем методе onConfigurationChanged() вы передаете соответствующий вызов setLayoutParams() для каждого ребенка. Если какой-либо дочерний элемент управления должен быть внутренне переориентирован, вы просто вызываете метод для этого дочернего элемента для выполнения переориентации. Этот дочерний процесс аналогичным образом вызывает методы для любого из его дочерних элементов управления, которые нуждаются во внутренней переориентации и т. Д.

10 голосов
/ 22 декабря 2012

Я нашел способ сделать это, используя события onRestoreInstanceState и onSaveInstanceState для сохранения чего-либо в Bundle (даже если вам не нужны сохраненные переменные, просто поместите что-нибудь туда, чтобы Bundle не пусто). Затем в методе onCreate проверьте, является ли Bundle пустым, и если это так, выполните инициализацию, если нет, то сделайте это.

6 голосов
/ 03 февраля 2017

Каждый раз, когда экран поворачивается, открытое действие заканчивается и снова вызывается onCreate ().

1. Вы можете сделать одно, сохранить состояние активности при повороте экрана, чтобы вы могли восстановить все старые вещи, когда функция onCreate () вызывается снова. Ссылка на эту ссылку

2. Если вы хотите предотвратить перезапуск действия, просто поместите следующие строки в файле manifest.xml.

  <activity android:name=".Youractivity"
  android:configChanges="orientation|screenSize"/>
6 голосов
/ 24 апреля 2014

Примечание: Я публикую этот ответ, если кто-то в будущем столкнется с той же проблемой, что и я. Для меня не хватило следующей строки:

android:configChanges="orientation"

Когда я поворачивал экран, метод `onConfigurationChanged (Configuration newConfig) не вызывался.

Решение: Мне также пришлось добавить «screenSize», даже если проблема была связана с ориентацией. Поэтому в файле AndroidManifest.xml добавьте следующее:

android:configChanges="keyboardHidden|orientation|screenSize"

Затем реализовать метод onConfigurationChanged(Configuration newConfig)

...