WindowManager.addView наложение (наложение) программной клавиши ИЛИ навигационная панель
Сегодня я видел приложение, которое перекрывает весь экран, включая навигационную панель (или софт-клавишу, которая возвращает назад, домой и т. Д.). это CF.Lumen(требуется Android 4.4+) от chainfire.
Я только что вспомнил, что это НЕ ВОЗМОЖНО при общем подходе, и многие ответы SO сказали мне. Поэтому я посмотрел вниз смайли коды от Lumens apk(извините цепной огонь), нашел 0x7d6
как спецификатор типа, который TYPE_SYSTEM_OVERLAY
, В общем, это делает вид наложений поверх экрана блокировки. Выглядит хорошо, но не перекрывает область навигационной панели. даже на экране блокировки. Я сделал замену MATCH_PARENT
в 9999
но это все еще не будет перекрывать область навигационной панели.
Я посмотрел вниз исходный код Android, нашел интересное, что имеет больше типов недокументированных.
FIRST_SYSTEM_WINDOW = 2000;
TYPE_NAVIGATION_BAR = FIRST_SYSTEM_WINDOW + 19;
TYPE_BOOT_PROGRESS = FIRST_SYSTEM_WINDOW + 21;
Я применил их к своему приложению, но получил сбой говорит, что разрешение отказано. Это требует INTERNAL_SYSTEM_WINDOW
ИЛИ что-то более недокументированное, чем SYSTEM_ALERT_WINDOW
, эти разрешения предоставляются только для системных приложений.
Вот мой код, чтобы добавить представление заполняет весь экран, кроме области навигационной панели.
Что я должен сделать, чтобы сделать это?(Сделать оверлей, включая область навигационной панели)
final WindowManager.LayoutParams paramsRL = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
PixelFormat.TRANSLUCENT);
windowManager.addView(view_floating, paramsRL);
1 ответ
Вот небольшой пример, который работает:
FrameLayout frameLayout = new FrameLayout(context);
frameLayout.setBackgroundColor(Color.BLACK);
frameLayout.setAlpha(0.5f);
windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED
| WindowManager.LayoutParams.FLAG_FULLSCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
PixelFormat.TRANSLUCENT);
//make sure height includes the nav bar size (get the dimension of whole screen)
params.height = screenHeight;
params.width = screenWidth;
windowManager.addView(frameLayout, params);
//add your view to this frameLayout
frameLayout.addView(....);
Вот три ключевые вещи:
TYPE_SYSTEM_OVERLAY (или любые подобные типы), которые могут отображать контент на весь экран.
FLAG_LAYOUT_NO_LIMITS, которая позволяет нам превышать допустимый размер.
Установка дополнительной высоты должна быть закрыта за софт-клавишами. Основная проблема заключалась в том, что когда мы устанавливаем параметры в match_parent, он устанавливает высоту экрана минус навигационная панель, я полагаю. Установка дополнительной высоты решает проблему.
Не используйте WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, этот флаг заставит панель навигации всегда отображаться. Не знаю почему.