Видеопроигрыватель отключает режим в Android, используя appcompat-v7

Я Theme.Holo кодовую базу из родного Holo ( Theme.Holo т. Д.) В appcompat-v7 ( Theme.AppCompat и т. Д.). В последнем разделе содержится tl; dr, если вы не хотите читать данные.


Проблема

Все работает, но у меня возникли проблемы с воспроизведением одного поведения, которое было довольно легко использовать с помощью старого ActionBar. У меня есть видеопроигрыватель, и в ландшафте я хочу, чтобы он вел себя как YouTube: скрыть (анимировать) элементы управления проигрывателем, панель приложений и строку состояния. При взаимодействии с пользователем элементы управления пользовательского интерфейса должны оставить этот режим «выключен» и вернуться в нормальное состояние. Затем таймер вернется в режим отключения света, если пользователь не коснется экрана в течение X секунд. Тот же код, который работал с ActionBar, не выполняет трюк с помощью Toolbar .

Итак, я использую:

  • Непрозрачная строка состояния
  • setSystemUiVisibility() используя одну из этих комбо:
    • View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN : View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
    • View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE : View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LOW_PROFILE | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
  • minSdkVersion – 16
  • Чтобы показать и скрыть ActionBar, я просто вызвал show() и hide() на нем
  • Для реализации такого же поведения на панели приложений, на которой я подклассифицировал Toolbar и добавил метод show() и hide() который делает то же самое (сначала просто используя setVisibility() , а затем используя анимации – получая те же результаты)

LAYOUT_STABLE сделал так, что панель приложения окажется в конце строки состояния, конечно (поскольку это подразумевает fitSystemWindows . Поскольку панель приложения является обычным представлением в иерархии представлений и не находится в декоре, например, в ActionBar, на него влияет Этот флаг. Это то, что я видел на экране:

Панель приложений за панель состояния

Не сразу понять, что границы панели инструментов, так как панель приложений темна на темноте, но вы можете видеть, что заголовок разрезан и «смещен». Это связано с тем, что панель инструментов была правильно установлена, но за панель состояния. Моя основная проблема заключалась в том, что нет публичного API для получения высоты строки состояния, прямоугольника или чего-либо еще, чтобы сдвинуть панель приложения вертикально, чтобы отобразить ниже строки состояния.

Тестирование проводилось в основном на N5 на LPX13D (последняя публичная сборка Lollipop на момент написания), но то же самое можно было увидеть на Android 4.4.


Хакерное решение

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

  1. В onResume :
    а. Call setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE) даже если я обычно этого не делал (пейзаж)
    б. Зарегистрировать OnPreDrawListener

  2. В OnPreDrawListener :
    а. Получить представление корня, используя View root = getRootView().findViewById(R.id.my_root)
    б. Получить высоту корневого представления: int rootTop = getAbsoluteViewTop(root) (см. Ниже)
    с. Используйте этот верх (намереваясь его как высоту строки состояния) как paddingTop для панели приложений
    д. Установите SystemUiVisibility, который я обычно использовал ( LAYOUT_STABLE т. Д.),
    е. Подавить прохождение чертежа

  3. В следующем проходе чертежа OnPreDrawListener регистрацию OnPreDrawListener

Это метод getAbsoluteViewTop() :

 private int getAbsoluteViewTop(View view) { int[] location = new int[2]; view.getLocationOnScreen(location); return location[LOCATION_Y]; } 

Tl; dr и вопрос

Tl; dr : нет способа сделать правильный режим «выключен» с помощью Toolbar если не будут использованы хакерские хаки.

Вопрос: есть ли официальный и чистый способ реализовать этот режим освещения с помощью Toolbar ?
Я не мог найти ничего в документах. Строка состояния недоступна (и все способы узнать ее размер, который вы можете найти на SO, сломаны, FYI). Но, может быть, я что-то упустил. Я хотел бы избавиться от этого взлома.

Solutions Collecting From Web of "Видеопроигрыватель отключает режим в Android, используя appcompat-v7"

Я нашел fitssystemwindows довольно ненадежным, когда вы хотите, чтобы некоторые элементы иерархии представлений были полноэкранными, а некоторые элементы были ниже строки состояния или панели действий. Но я никогда не видел панель действий за панель состояния. Является ли панель инструментов установленной как панель действий? Вы используете Window.FEATURE_ACTION_BAR_OVERLAY ? В любом случае, если все, что вам нужно, это получить несколько пикселей для paddingTop в onResume() , может быть немного чище (хотя и взломанно), чтобы сделать что-то вроде следующего, а не использовать OnPreDrawListener s.

 class MyVideoActivity extends Activity { Toolbar bar; //... @Override protected void onResume() { super.onResume(); bar.setPaddingTop(getStatusBarHeight()); } int getStatusBarHeight() { int result = 0; Resources res = getResources(); int resourceId = res.getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { result = res.getDimensionPixelSize(resourceId); } return result; } } 

Не уверен, что это поможет, но вы посмотрели на использование

 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 

В методе onCreate вашей видеоинформации? Это может быть хорошей отправной точкой. Это в основном скрывает строку состояния и делает мое видео на весь экран.

Это макет, который я также использую:

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@color/black"> <VideoView android:id="@id/videoSurface" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:layout_centerInParent="true" android:layout_alignParentTop="true" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_alignParentRight="true" android:layout_gravity="center" /> </RelativeLayout> 

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