Я переношу кодовую базу из родного Холо (Theme.Holo
и т.д.) в appcompat-v7
(Theme.AppCompat
и т.д.). В последнем разделе содержится tl; dr, если вы не хотите читать детали.
Проблема
Все работало, но у меня были проблемы, реплицировавшие одно поведение, которое было довольно легко использовать с помощью старого ActionBar. У меня есть видеоплеер, и в ландшафте я хочу, чтобы он вел себя как YouTube: скрыть (анимировать) элементы управления проигрывателем, панель приложений и строку состояния. При взаимодействии с пользователем элементы управления пользовательского интерфейса должны оставить этот режим "выключен" и вернуться в нормальное состояние. Затем таймер перейдет в режим отключения света, если пользователь не коснется экрана в течение X секунд. Тот же код, который работал с ActionBar, не выполняет трюк с Toolbar
.
Итак, я использую:
- Прозрачная строка состояния
-
setSystemUiVisibility()
используя одну из этих комбо:- default:
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
- default:
-
minSdkVersion
- 16 - чтобы показать и скрыть ActionBar, я просто назвал
show()
иhide()
на нем - реализовать такое же поведение на панели приложения я подкласса
Toolbar
и добавить методshow()
иhide()
, который делает то же самое (сначала просто используяsetVisibility()
, а затем используя анимацию - получение того же результаты)
LAYOUT_STABLE
сделал так, что панель приложения окажется в конце строки состояния, конечно (поскольку это подразумевает fitSystemWindows
. Так как панель приложения является обычным представлением в иерархии представлений и не находится в декоре, например, ActionBar был, на него повлиял этот флаг. Это было то, что я видел на экране:
Непонятно, какие границы панели инструментов есть, так как панель приложения темна на темноте, но вы можете видеть, что заголовок разрезан и "смещен". Это связано с тем, что панель инструментов была правильно установлена, но за панель состояния. Моя основная проблема заключалась в том, что нет публичного API, чтобы получить высоту строки состояния, прямоугольник или что-то еще, чтобы сдвинуть панель приложения по вертикали, чтобы показать ниже строки состояния.
Тестирование проводилось в основном на N5 на LPX13D (последняя публичная сборка Lollipop на момент написания), но то же самое можно было увидеть на Android 4.4.
Хакерное решение
Тем не менее, после довольно долгого времени и некоторых неудачных попыток заставить его работать не слишком-взломанным способом (включая довольно отчаянную попытку самим поместить его в декор), я прибегал к этому мерзкому способу заставляя его работать:
-
В
onResume
:
а. ВызовитеsetSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE)
, даже если я обычно этого не делал (пейзаж)
б. ЗарегистрируйтеOnPreDrawListener
-
В
OnPreDrawListener
:
а. Получить представление корня с помощьюView root = getRootView().findViewById(R.id.my_root)
б. Получить высоту корневого представления:int rootTop = getAbsoluteViewTop(root)
(см. Ниже)
с. Используйте этот верх (намереваясь его как высоту строки состояния) в качестве paddingTop для панели приложений
д. Установите SystemUiVisibility, который я обычно использую (LAYOUT_STABLE
и т.д.)
е. Подавить прохождение чертежа - В следующем проходе чертежа отмените регистрацию
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). Но, может быть, я что-то упустил. Я хотел бы избавиться от этого взлома.