Изящно обрабатывать изменение ориентации экрана во время начала активности

StackOverflow https://stackoverflow.com/questions/2434071

Вопрос

Я пытаюсь найти способ правильно обработать настройку деятельности, в котором его ориентация определяется по данным в намерении, которые его запустили. Это для игры, в которой пользователь может выбрать уровни, некоторые из которых представляют собой ориентацию на портрету INT, а некоторые - ландшафтная ориентация. Проблема, с которой я сталкиваюсь, заключается в том, что setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) Не вступает в силу, пока деятельность не будет полностью загружена. Это проблема для меня, потому что я делаю некоторую загрузку и обработку изображений во время запуска, что я хотел бы сделать только один раз.

В настоящее время, если пользователь выбрал ландшафтный уровень:

  • Занятие начинается oncreate (), дефолт на портрет
  • Обнаруживает, анализируя его намерение запуска, чтобы оно было в ландшафтной ориентации
  • Продолжается независимо от всего пути к OnResume (), загрузка информации и выполнение других задач настроек
  • На этом этапе SetRequestErientation начинается, поэтому приложение проходит через OnPause () в OnDestroy ()
  • Затем он снова начинается с Oncreate () и работает до OnResume (), повторяя установку из более раннего

Есть ли способ избежать этого и не выполнять нагрузку дважды? Например, в идеале, это деятельность узнает, прежде чем даже был назван даже на Create, должен ли оно быть ландшафтом или портретом в зависимости от какого -либо свойства намерения запуска, но если я не пропустил что -то, что невозможно. Мне удалось взломать способ не повторять нагрузку, проверив boolean Перед трудоемкими этапами загрузки, но это не похоже на правильный способ сделать это. Я полагаю, что мог бы отменить onSaveInstanceState, но это потребует много дополнительного кодирования. Есть ли простой способ сделать это?

Спасибо!


Решение:

Согласно ответу Даниэля, это было на самом деле довольно легко исправить. Мне просто нужно было внести несколько небольших изменений. В моей деятельности «меню», где игрок выбрал бы, какой уровень играл, мне просто нужно было добавить, если/иначе проверить, чтобы выбрать, какой класс будет запущен с моего намерения. Это было сделано с помощью простого INT, представляющего портрет или ландшафт, определяемый, когда игрок выбрал уровень. Затем я создал второй класс, расширяющий мой класс «GameLogic»; Это класс, который содержал большую часть кода для самой игры, а не меню, инструкции и т. Д.

public class GameLandscape extends GameLogic{
}

Буквально это просто и совершенно пусто. Таким образом, он унаследовал весь код от моего предыдущего действия, где я уже закодировал его, чтобы справиться с вещами по -разному в зависимости от ориентации. Наконец, мне просто нужно было добавить линию к манифесту, заявив, что GamelandScape всегда будет работать в ландшафте, и GameLogic всегда будет работать в портрете.

Так что действительно простая проблема.

Это было полезно?

Решение

Вы можете сделать два действия - одно для уровней портретов, другое для ландшафтных уровней, а затем установить ориентацию деятельности в AndroidManifest.xml, используя android:screenOrientation атрибут. Вам даже не придется дублировать код, если вы используете наследство; Используйте свою текущую деятельность в качестве базовой деятельности и просто создайте ландшафт/портретную деятельность в качестве подклассов этой деятельности.

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

Другие советы

Вы также можете переопределить onRetainNonConfigurationInstance(). Анкет Это позволяет временно хранить один товар, который вы можете получить, позвонив, позвонив getLastNonConfigurationInstance(). Анкет Таким образом, вы можете загрузить все необходимые вам вещи, и в вашем onRetainNonConfigurationInstance() Метод вы можете сохранить все в структуру данных и вернуть его. В твоем onCreate() вы можете позвонить getLastNonConfigurationInstance() И если это возвращает нулевую нагрузку, загрузите все свои вещи, если он что -то вернет, то у вас все это загружено. Вот быстрый пример:

public class MyActivity extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        DataStructure myData = (DataStructure)getLastNonConfigurationInstance();
        if(myData == null)
        {
            // Load everything in
        }
        else
        {
            // Unpack myData
        }
    }

    @Override
    public Object onRetainNonConfigurationInstance()
    {
        DataStructure myData = new DataStructure();
        // Put everything in to myData
        return myData;
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top