Android изменяет ориентацию звонков на создание - PullRequest
14 голосов
/ 23 июня 2010

Я создал экран поиска, который имеет одну вкладку для ключевых слов, фильтров и кнопку поиска и три дополнительных вкладки для различных типов результатов (каждая из которых содержит ListView с ArrayAdapter). При запуске действия разработчик может при желании передать результаты как дополнительные Parcelable[], если поиск уже был выполнен. В методе onCreate() я создаю каждую из трех вкладок для прохода через Parcelable[].

Когда я вызываю поиск с помощью кнопки на вкладке фильтра, я очищаю вкладки и воссоздаю их с новыми результатами, что прекрасно работает. Проблема в том, что когда вы поворачиваете устройство, кажется, что поддержка автоматического переключения ориентации в Android воссоздает всю активность, вызывая onCreate(). Это означает, что мои результаты поиска сбрасываются до Parcelable[], пропущенного при запуске действия.

Единственное решение, которое у меня было до сих пор, - это вызвать finish(), а затем startActivity(), чтобы по существу возобновить действие с новыми результатами. Я уверен, что должно быть намного более простое решение, и что я сделал что-то чрезвычайно нубистское.

Есть ли лучший способ сделать это?

Ответы [ 3 ]

31 голосов
/ 23 июня 2010

Конечно, есть.Просто добавьте атрибут configChanges в ваш AndroidManifest.xml, например:

<activity android:name=".MyActivity" 
          android:configChanges="orientation|keyboardHidden" /> 

Перезапуск активности при вращении Android Как отключить изменение ориентации на Android? http://developer.android.com/guide/topics/manifest/activity-element.html#config

14 голосов
/ 15 марта 2013

То, что вы описываете, является поведением по умолчанию. Вы должны обнаружить и обработать эти события самостоятельно, добавив:

android:configChanges

в манифест, а затем изменения, которые вы хотите обработать. Так что для ориентации вы бы использовали:

android:configChanges="orientation"

и для открытия или закрытия клавиатуры вы должны использовать:

android:configChanges="keyboardHidden"

Если вы хотите обработать оба, вы можете просто разделить их командой pipe, как:

android:configChanges="keyboardHidden|orientation"

Это вызовет метод onConfigurationChanged во всех вызываемых Activity. Если вы переопределите метод, вы можете передать новые значения.

Надеюсь, это поможет.

1 голос
/ 02 января 2019

Один из вариантов - использовать android:configChanges="orientation", чтобы сообщить Android, что вы хотите самостоятельно обрабатывать изменения конфигурации, вместо того, чтобы заново создавать действие.Однако это не рекомендуется:

Когда изменение конфигурации происходит во время выполнения, действие отключается и перезапускается по умолчанию, но объявление конфигурации с этим атрибутом предотвратит перезапуск действия.Вместо этого действие продолжает выполняться, и вызывается его метод onConfigurationChanged ().Примечание. Следует избегать использования этого атрибута и использовать его только в качестве крайней меры.Пожалуйста, прочитайте Обработка изменений времени выполнения для получения дополнительной информации о том, как правильно обрабатывать перезапуск из-за изменения конфигурации.( Источник )

Существует другой способ сохранить объект во время изменения конфигурации: ViewModel может использоваться для определения класса оболочки для вашегоданные.Кажется, что каждый экземпляр Activity имеет свой собственный набор ViewModels, доступный через

MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);

, и если вы используете в нем LiveData, вы можете подписаться на изменения данных, как указано в документации.Вот их пример на случай, если в какой-то момент связь прекратится:

Компоненты архитектуры предоставляют вспомогательный класс ViewModel для контроллера UI, который отвечает за подготовку данных для интерфейса пользователя.Объекты ViewModel автоматически сохраняются во время изменений конфигурации, поэтому данные, которые они хранят, сразу же становятся доступны для следующего действия или экземпляра фрагмента.Например, если вам нужно отобразить список пользователей в вашем приложении, обязательно назначьте ответственным за получение и сохранение списка пользователей для ViewModel вместо действия или фрагмента, как показано в следующем примере кода:

public class MyViewModel extends ViewModel {
    private MutableLiveData<List<User>> users;
    public LiveData<List<User>> getUsers() {
        if (users == null) {
            users = new MutableLiveData<List<User>>();
            loadUsers();
        }
        return users;
    }

    private void loadUsers() {
        // Do an asynchronous operation to fetch users.
    } } You can then access the list from an activity as follows:

public class MyActivity extends AppCompatActivity {
    public void onCreate(Bundle savedInstanceState) {
        // Create a ViewModel the first time the system calls an activity's onCreate() method.
        // Re-created activities receive the same MyViewModel instance created by the first activity.

        MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
        model.getUsers().observe(this, users -> {
            // update UI
        });
    } }

Если действие воссоздается, оно получает тот же экземпляр MyViewModel, который был создан первым действием.Когда действие владельца завершено, платформа вызывает метод onCleared () объектов ViewModel, чтобы очистить ресурсы.

...