Как управлять приоритетом оверлея WindowManager в Oreo?

У меня есть оверлей для моего приложения, OV1, который по сути представляет собой кнопку, которую пользователь может перемещать на своем экране. Когда этот оверлей нажат, он порождает второй оверлей, OV2, который содержит несколько суб-кнопок, расположенных вокруг текущего местоположения OV1. OV2 также затемняет остальную часть экрана, пока присутствует, используя флаг WindowManager.LayoutParams.FLAG_DIM_BEHIND.

Одна проблема, с которой я столкнулся при первоначальной реализации вышеизложенного, заключается в том, что эффект затемнения был наложен на все, что не является OV2, включая OV1, затемнение и отключение щелчка, что предотвращает закрытие OV2, поскольку OV1 является кнопкой переключения. Решение, которое я нашел, заключалось в настройке параметров макета по-разному для каждого оверлея:

OV1 получает:

params.type = WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;

В то время как OV2 получает:

params.type = WindowManager.LayoutParams.TYPE_PHONE

Поскольку у OV1 был более высокий приоритет, он всегда оставался поверх OV2, поэтому FLAG_DIM_BEHIND не влиял на него, и пользователь мог нормально взаимодействовать с OV1, чтобы закрыть субкнопочное меню OV2.

Это всегда работало нормально, пока я не начал обновлять приложение для Android API 27 (Oreo). В рамках необходимых изменений мне пришлось изменить типы параметров обоих оверлеев на WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, поэтому я потерял возможность назначать OV1 более высокий приоритет, чтобы он оставался поверх OV2. Есть ли альтернативный способ воспроизвести это поведение, гарантируя, что OV1 остается самым верхним оверлеем, или вынуждая его выводить его на передний план всякий раз, когда создается OV2?


person PM4    schedule 31.05.2018    source источник


Ответы (1)


Хотя я так и не нашел решения для этого, один обходной путь состоит в том, чтобы повторно прикрепить оверлеи к диспетчеру окон в предполагаемом порядке (когда несколько представлений типа TYPE_APPLICATION_OVERLAY добавляются в диспетчер окон, самые последние идут вверху), вызывая removeViewImmediate (), за которым следует addView () для представления, которое вы хотите разместить на вершине.

Это некрасиво, так как пользователь может видеть, что наложение перестает существовать на долю секунды, но до тех пор, пока не будет лучшего способа, это придется делать.

person PM4    schedule 16.06.2018