onApplyWindowInsets вызывается со странной верхней вставкой - PullRequest
0 голосов
/ 06 февраля 2019

У меня есть приложение Android, в теме которого указаны следующие настройки:

<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:statusBarColor">@android:color/transparent</item>

<item name="android:windowDrawsSystemBarBackgrounds">true</item>

Вид сверху в иерархии переопределяет onApplyWindowsInsets().Реализация просто записывает WindowInsets, которое было передано, затем вызывает метод суперкласса, регистрирует результат и возвращает его - ничего не изменяется.Журнал также показывает, что метод суперкласса не изменяет вставки.

Теперь я получаю странный верхний вкладыш, который всегда кажется на 56–72 дп больше, чем я ожидал:

Platform           DPI    Layout                  Inset         Bar          Difference

Android x86_64 8.1 MDPI   Landscape               88 px/dp      24 px/dp     64 px/dp
                          Landscape, split        80 px/dp      24 px/dp     56 px/dp
Anbox              MDPI   Window                  64 px/dp      None         64 px/dp
LineageOS 15.1     XXHDPI Portrait                240 px/80 dp  72 px/24 dp  168 px/56 dp
                          Portrait, split/top     216 px/73 dp  72 px/24 dp  144 px/48 dp
                          Portrait, split/bottom  144 px/48 dp  None         144 px/48 dp
SDK Emulator (6.0) HDPI   Portrait                120 px/80 dp  36 px/24 dp  84 px/56 dp

Примечание: в ландшафтном режиме два последовательных вызова onApplyWindowInsets() выполняются два раза, здесь сообщаются только последние.

Вид фактически не выходит за пределы верхней частиЧто видно: если я нарисую область размером 24 пикселя в верхней части моего обзора, она появится в верхней части видимой области (т. е. под строкой состояния, если она есть), а не за пределами экрана.

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

Влево / вправоНасколько я могу судить, значения / bottom кажутся нормальными.

Как я могу это исправить?Я что-то пропускаю?

1 Ответ

0 голосов
/ 08 февраля 2019

Поскольку у меня до сих пор нет объяснения сообщаемым значениям, я предполагаю, что это либо ошибка, либо плохо документированная функция, которая, тем не менее, присутствует во многих (если не во всех) версиях Android.

К счастью,по крайней мере, в API 23+ есть другой метод для получения вставок окна, а именно путем вызова View#getWindow().getRootView().getRootWindowInsets().Похоже, что имеет несколько собственных ошибок , а именно сообщает о неверных вставках для панели навигации, но объединение двух результатов мне помогло.

  • Сохранение вставленных в * вставок onApplyWindowsInsets(), отбрасывая только верхний.
  • Переопределите onSizeChanged() для представления и в нем вызовите View#getRootWindowInsets(), чтобы получить верхнюю вставку (игнорируйте остальные).

Объединенные значения сработали для меня.

К сожалению, это не будет работать для API 20–22, который не реализует View#getRootWindowInsets().Здесь вам нужно будет сделать некоторые догадки.К счастью, это проще, поскольку эти API еще не реализуют разделенный экран - верхняя вставка будет высотой строки состояния, если вы явно не запросили ее скрытие (в этом случае это 0).Если строка состояния видна, ее высоту можно определить следующим образом:

Resources resources = view.getResources();
int shid = resources.getIdentifier("status_bar_height", "dimen", "android");
padding_top = (shid > 0) ? resources.getDimensionPixelSize(shid) : 0;
...