Сделать фрагменты на весь экран программными
У меня есть 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();
}