Изящно обрабатывать изменение ориентации экрана во время начала активности
-
19-09-2019 - |
Вопрос
Я пытаюсь найти способ правильно обработать настройку деятельности, в котором его ориентация определяется по данным в намерении, которые его запустили. Это для игры, в которой пользователь может выбрать уровни, некоторые из которых представляют собой ориентацию на портрету 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;
}
}