Translate

суббота, 10 декабря 2016 г.

Красим статус бар на ANDROID и IOS

Доброго времени суток!

    Долгое время искал решение как можно покрасить статус бар (шторку) на Android устройствах выше 5 версии.
Про IOS мы не будем говорить, потому что, это сделано в FMX из коробки (в демо проекте будет дополнение чтобы в run-time применять покраску)

    Примерно год назад я создал модуль, который реализовывал эту фичу, но он был не полноценен, на некоторых устройствах покраска происходила только после смены ориентации экрана, что неправильно. Проблемы с покраской были у устройств на базе процессоров Intel и arm64-v8a. В том модуле я использовал изменение флагов JWindow в run-time, а именно добавлял FLAG_TRANSLUCENT_STATUS

Но видимо изменение флагов в run-time некорректно обрабатывается…
Решение пришло на днях, попробовать подменить стиль для MainActivity и добавить нужные флаги в XML разметку.


ВАЖНО: Это будет работать только с включенным параметром Include Splash Image
  • Project -> Options -> Application -> Include splash image = true

Стиль получился вот таким

 


Как видим используется тот же флаг, но уже в стиле.
true
При установке этого параметра происходит следующее:
  • Форма размещается под статус баром, но не под панелью навигации (при её наличии)
  • Статус бар становится прозрачным (на разных устройствах это будет смотреться по разному,  в зависимости от лаунчеров)
false
Этот параметр мы отключаем, чтобы панель навигации (при её наличии) оставалась чёрного цвета и форма не занимала 100% экрана

Теперь перейдём к Delphi
  • сохраняем этот стиль в папке с проектом как styles.xml
  • открываем студию, заходим в Deployment (выбираем платформу Android)
  • добавляем наш styles.xml и указываем в RemotePath путь res\values-v21\
  • не забываем что две конфигурации, Debug и Release в обоих должно быть одинаково
Можете на этом моменте протестировать и увидите, что форма залезла под статус бар.

Есть несколько решении
  • Положить TRectangle (только Android)
    • Align = MostTop
    • Height = ****
    • Fill.Color = Любой
  • Положить TRectangle (Кроссплатформенно Android/IOS)
    • Align = Client
    • Fill.Color = $FFE0E0E0 (Любой)
    • Margins.Top = ****
Теперь объясню почему второй способ является кроссплатформенным, тут все дело в реализации покраски статус бара в IOS. Покраска осуществляется сменой цвета заливки формы:
Form1.Fill.Color := TAlphaColorRec.Red;


И чтобы ваша форма не была вся красного цвета (как в нашем случае), вам потребуется положить например TRectangle под все элементы и тогда статус бар будет одного цвета, и контролы на фоне TRectangle будут смотреться уютно и правильно.

**** В андроиде статус бар обычно имеет высоту в 24 пикселя, но на кастомных прошивках или лаунчерах значение может меняться, поэтому в модуле есть нативное определение высоты статус бара

Модуль FMX.StatusBar был упрощён до минимума и ориентирован на второй вариант, т.к. он кроссплатформенный

1) пишем в конец главного модуля (перед end.)
initialization
TmyWindow.Init;
2) в событии OnShow
TmyWindow.StatusBarColor(Self, TAlphaColorRec.Red);
3) в событии OnResize
TRectangle.Margins.Top := TmyWindow.StatusBarHeight;
На этом всё, вот собственно результат
Работает стабильно на всех устройствах выше Android 5 и IOS 7
Проект на GitHub