Android изменяет ориентацию звонков на создание

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

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

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

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

3 ответа

Решение

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

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

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

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

android:configChanges

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

android:configChanges="orientation"

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

android:configChanges="keyboardHidden"

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

android:configChanges="keyboardHidden|orientation"

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

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

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

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

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

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

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

Компоненты архитектуры предоставляют вспомогательный класс ViewModel для контроллера пользовательского интерфейса, который отвечает за подготовку данных для пользовательского интерфейса. Объекты 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, чтобы очистить ресурсы.

Другие вопросы по тегам