Подтвердить что ты не робот

Разрешить поворот/пейзаж в одном фрагменте

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

Моя мысль заключалась в том, чтобы установить android:configChanges="orientation" в манифесте и вызвать getActivity().setRequestedScreenOrientation() в onResume() всех фрагментов, заблокировав до SCREEN_ORIENTATION_PORTRAIT в трех из них, но до SCREEN_ORIENTATION_UNSPECIFIED в том, что необходимо разрешить вращение, но это не работает. Приложение остается в портретном режиме.

Есть ли способ достичь этого?

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

4b9b3361

Ответ 1

Переопределить setUserVisibleHint() в каждом фрагменте.

В портрете только фрагменты:

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if(isVisibleToUser) {
        Activity a = getActivity();
        if(a != null) a.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }
}

в портретном/альбомном фрагменте:

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if(isVisibleToUser) {
        Activity a = getActivity();
        if(a != null) a.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
    }
}

Это позволит всей активности вращаться в одном фрагменте, но фиксировать ее на портрете в других.

Ответ 2

Одна вещь, которая работала для меня, заключалась в том, чтобы просто поставить

getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);

В верхней части методов OnCreateView() для каждого из фрагментов. Вы бы хотели заменить ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR на соответствующую константу SCREEN_ORIENTATION.

Как только я это сделал, он отлично работал на ICS. Вам не нужно настраивать манифест для конкретной активности.

Ответ 3

Проблема в том, что если вы включили configChanges, вам необходимо обработать метод onConfigurationChanged() в вашей активности/фрагментах.

Считаем, что если вы нажмете getActivity().setRequestedScreenOrientation(), вам придется вручную вызвать setContentView() снова, чтобы переустановить макет ландшафта.

Также установка `UNSPECIFIED 'не изменится на пейзаж, она останется там, где она есть.

Я использовал бы getActivity().setRequestedScreenOrientation(SCREEN_ORIENTATION_PORTRAIT) для фрагментов портрета. И getActivity().setRequestedScreenOrientation(SCREEN_ORIENTATION_LANDSCAPE) для фрагментов ландшафта.

Это приведет к восстановлению макета активности, а это значит, что вам нужно будет отслеживать последнюю страницу ViewPager, где вы находитесь, чтобы убедиться, что вы показываете, что после того, как макет был воссоздан по умолчанию, назад к этому фрагменту, прежде чем они будут показывается пользователю и фрагмент onResume().

Это будет неудобно, но возможно.

Ответ 4

во фрагменте, который вы хотите установить, просто добавьте в свой onCreate/onCreateView

getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

в других фрагментах вы хотите разрешить мульти ориентацию добавить

getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);

Ответ 5

Напишите некоторый код в AndroidManifest.xml для конкретного тега активности.

android:configChanges="orientation|screenSize".

И написать код во фрагменте по методу onCreateView,
для портрета:

getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
setRetainInstance(true);

для ландшафта:

getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setRetainInstance(true);