2015-11-27 5 views
1

У меня есть приложение со многими видами деятельности и которое имеет макеты, подходящие как для телефонов (SFF), так и для планшетов (LFF). Для устройств LFF автоматическое восстановление активности каркаса при изменении ориентации (пейзаж < -> портрет) прекрасно работает и делает то, что я хочу. При работе на устройстве SFF я могу заблокировать ориентацию как портрет, используя Activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT).Вызывает активность при изменении ориентации без перезапуска текущей активности

При работе на устройстве SFF я хочу запустить другое действие, когда устройство физически повернуто в альбомную ориентацию. (Оставим в стороне обсуждение вопроса о том, является ли хорошим конструктивным принципом запуск другой активности при вращении.)

Первоначально я использовал OrientationEventListener для контроля вращения, но это не срабатывает в случае устройства SFF, чья «естественная» ориентация это пейзаж. OrientationEventListener.onOrientationChanged() сообщит 0 градусов (+/- 45) и WindowManager.getDefaultDisplay().getRotation() сообщит Surface.ROTATION_0, когда в альбомной ориентации. Я не могу найти способ определить «естественную» ориентацию устройства, чтобы компенсировать указанные значения вращения. Есть пара вопросов SO, которые обсуждают это, но ни один из них не имеет удовлетворительного ответа.

Другим вариантом было бы использовать android:configChanges="orientation|screenSize" в манифесте и уловить изменение ориентации в onConfigurationChanged(). Проблема заключается в том, что он побеждает поведение по умолчанию для устройств LFF и которое я хочу сохранить. Ужасный хак действительно представляет собой: дублируйте каждое действие в манифесте с версиями LFF и SFF, один с одним и без набора android:configChanges, а затем активируйте действие соответствующей версии при каждом запуске нового действия.

Мое текущее решение не использует ни android:configChanges, ни setRequestedOrientation(), и OrientationEventListener. Вместо этого у меня есть логический ресурс, is_landscape, определенный в values-land, и я проверяю это в соответствующих действиях 'onCreate(). Это имеет недостатки, которые, при повороте на альбомный:

  • портрета только деятельность, которая собирается запустить ландшафтную деятельность, первым пересоздался рамками, что является достаточно дорогим и может задержать запуск ландшафта Мероприятия; и
  • Активность только для портрета потеряет некоторое состояние, которое в противном случае обычно было бы сохранено каркасом и было доступно по возвращении из ландшафтной активности.

Может ли кто-нибудь предложить лучшее решение, включая, возможно, способ обнаружить «естественную» ориентацию устройства? Мне нужно это, чтобы вернуться к Android 4.0.

ответ

0

Вы должны проверить естественное направление, используя комбинацию getRotation и getResources().getConfiguration().

public int getDefaultOrientation() { 
    WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE); 
    Configuration config = getResources().getConfiguration(); 
    int rotation = windowManager.getDefaultDisplay().getRotation(); 

    if (((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) && 
      config.orientation == Configuration.ORIENTATION_LANDSCAPE) 
     || ((rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) &&  
      config.orientation == Configuration.ORIENTATION_PORTRAIT)) { 
     return Configuration.ORIENTATION_LANDSCAPE; 
    } else { 
     return Configuration.ORIENTATION_PORTRAIT; 
    } 
} 
+0

Это действительно работает, если вызывается 'Activity.setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)'? – awy

+0

@awy: да, это работает – JiTHiN

+0

На самом деле это не так, но неважно. Поскольку я могу назвать код, который вы предлагаете обнаружить естественную ориентацию, прежде чем я когда-либо назову 'Activity.setRequestedOrientation()', этого достаточно. Спасибо, что указал мне в правильном направлении. – awy

Смежные вопросы