it-swarm.com.ru

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

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

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 строка состояния перемещается вверх и вниз после завершения изменения вкладки. Я не уверен, как реализовать это, поэтому любые советы по этому аспекту будут оценены.

19
Eric Ahn

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

Хитрость заключается не в том, чтобы использовать панель действий 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.

12
Eric Ahn

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

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
LordMarty