Сделать фрагменты на весь экран программными

У меня есть ViewPager и FragmentPagerAdapter, созданный в одном действии с тремя фрагментами. Все фрагменты загружаются одновременно и хранятся в памяти, используя

mPager.setOffscreenPageLimit(2);

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

Как мне сделать только полный фрагмент предварительного просмотра камеры, сохраняя при этом два других фрагмента? Я пробовал использовать темы, что означает разрыв панели действий.

Программный вызов следующего не помогает, потому что он заставляет всю активность быть полноэкранным (и, следовательно, двумя другими фрагментами вместе с ней):

requestWindowFeature(Window.FEATURE_NO_TITLE); 
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);

Я также попытался реализовать ViewPager.OnPageChangeListener:

public void onPageSelected(int position) {
    if(position == 1)
        getActionBar().hide();
    else
        getActionBar().show();
}

Это скрывает панель действий, но она не скрывает строку состояния системы (я говорю о том, где отображаются уведомления, значки состояния и время), а также экранирование скрытой/шоу-панели действий также очень изменчиво при прокрутке.

Для примера того, что я хочу сделать точно, см. Snapchat - им удастся полностью очистить прокрутку между камерой и другими фрагментами.

Редактировать:

Поэтому я изменил свой onPageSelected на это:

public void onPageSelected(int position) {
    if(position == 1) {
        MainActivity.this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        MainActivity.this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
    } else {
        MainActivity.this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        MainActivity.this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
    }
}

Это позволяет мне изменять отображение строки состояния или нет. Тем не менее, это вызывает большое количество битков. Такая же проблема с панелью действий.

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

Ответ 1

Я понял, как это сделать, хотя это определенно рушится.

Хитрость заключается не в том, чтобы использовать панель действий Android, это сделать свой собственный в ваших файлах макетов.

Я определил еще два RelativeLayouts в моем коде:

<RelativeLayout
    android:id="@+id/padding"
    android:layout_width="fill_parent"
    android:layout_height="25dip"
    android:layout_alignParentTop="true"
    android:background="@color/abs__background_holo_dark" />

<RelativeLayout
    android:id="@+id/fake_action_bar"
    android:layout_width="fill_parent"
    android:layout_height="48.0dip"
    android:layout_below="@id/padding" >

<!-- stuff here -->

</RelativeLayout>

Верхний RelativeLayout является дополнением к строке состояния Android. Я установил его на 25dip, но он может меняться - вероятно, было бы лучше всего установить это значение программно. Также вам необходимо установить его на черный цвет, чтобы он соответствовал цвету строки состояния и сделал интерфейс более естественным.

Нижняя RelativeLayout предназначена для вашей поддельной панели действий. Вам нужно заполнить все, что нужно вашему бару (текст заголовка, кнопки и т.д.) В этом RelativeLayout. Я установил его на 48dip, но опять же, это будет отличаться, и вы должны, вероятно, установить его программным путем.

В Управлении, где размещаются ваши фрагменты, ViewPager и FragmentPagerAdapter, вам нужно установить флаги, указывающие Android, чтобы сделать панель состояния оверлейной:

WindowManager.LayoutParams params = getWindow().getAttributes();
params.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;

Теперь нам нужно заставить панель состояния скрывать и показывать, когда мы переключаем фрагменты. Предложите своей активности реализовать ViewPager.OnPageChangeListener, а затем используйте следующий код:

@Override
public void onPageScrollStateChanged(int state) {
    switch(state) {
    case ViewPager.SCROLL_STATE_IDLE:
        if(mPosition == 1) {
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        } else {
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
        }
    }
}

@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

}

@Override
public void onPageSelected(int position) {
    mPosition = position;
}

Мы отслеживаем номер страницы, используя onPageSelected, и используем ее в onPageScrollStateChanged для динамического скрытия/отображения строки состояния в зависимости от того, какой фрагмент отображается в данный момент. Вы не можете сделать это в onPageSelected, потому что это приведет к тому, что строка состояния будет отображаться наполовину через салфетки.

Вам также нужно обязательно добавить соответствующий код для вашей поддельной панели действий - для кнопок это будет OnClickListener.

Ответ 2

Во-первых, в активности/фрагменте вы хотите скрыть строку состояния: Сделать публичный статический фрагмент.

public static Fragment QSFrag;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    QSFrag = this;
}

Затем в вашем onPageSelected:

public void onPageSelected(int position) {
        // TODO Auto-generated method stub
        if(position == 1){
            mActionBar.hide();              


            YourActivityWithNoStatusOrActionBar.QSFrag.getActivity().getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);


        }else{

            mActionBar.show();
             // mActionBar.setSelectedNavigationItem(position); I use this, not sure u need/want it.
        }

    }

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

Ответ 3

Вы можете использовать этот код в onCreate:

 setTheme(android.R.style.Theme_Translucent_NoTitleBar_Fullscreen);
 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
 if (getSupportActionBar() != null) {
     getSupportActionBar().hide();
 }