Изящная обработка изменения ориентации экрана во время начала активности - PullRequest
4 голосов
/ 12 марта 2010

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

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

  • действие начинается с onCreate (), по умолчанию - портрет
  • обнаруживает, что анализ его запуска Намерение, что он должен быть в альбомной ориентации
  • продолжается независимо от пути к onResume (), загрузки информации и выполнения других задач настройки
  • в этот момент включается setRequestedOrientation, поэтому приложение запускается от onPause () до onDestroy ()
  • затем он снова запускается из onCreate () и запускается в onResume (), повторяя настройку из более раннего

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

Спасибо!


Решение:

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

public class GameLandscape extends GameLogic{
}

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

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

Ответы [ 2 ]

6 голосов
/ 12 марта 2010

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

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

2 голосов
/ 12 марта 2010

Вы также можете переопределить 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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...