Translucent на андроид и adjustResize
Возможность использовать translucent в андроид появилась ещё в KITKAT. И выглядит в правильном дизайне это довольно эффектно. А с появлением моды на девайсы с "Чёлками", кажется, просто необходимой вещью в любом тёплом ламповом стартапчике.
Давайте представим ситуацию: вы запилили офигительно красивый, скроллящийся под StatusBar и NavigationBar дизайн. И вот вы добавляете поле ввода и понимаете, что adjustResize у вас не работает.
Вы можете:
- Забить, – пользователь сам закроет клавиатуру, чтобы посмотреть что под ней.
- Отказаться от translucent, стиль – это не ваше, всё будет олдово, надёжно, как у всех.
- Как только пользователь начинает скроллить, скрывать клавиатуру. Вы молодец! Всё правильно сделали, skype даже под ios так делает! А там и прозрачности-то нет.
- Вынести все поля ввода на отдельные экраны. Как бонус — каждый лишний переход на экран, минус удобство и конверсия.
- Запилить свой adjustResize.
Все сложности translucent
При реализации translucent есть несколько сложностей:
- Нужно учитывать дизайн для девайсов меньше KITKAT (думаю что в 2019 году, это уже почти не актуально, особенно для новых проектов). Пожалуй, для девайсов меньше LOLLIPOP может овчинка выделки не стоит? Там нельзя получить прозрачный NavigationBar и "Чёлок" на таких девайсах тоже не было.
- Если уж вы задумались о translucent, то скорее всего хотите что-то сложнее, чем статичный задний фон, что-то скролящееся под StatusBar и NavigationBar, что-то что при помощи fitsSystemWindows не сделать, а значит высоту StatusBar и NavigationBar придётся подставлять динамически.
- И наконец главное: adjustResize работает только без translucent или для тех View которые fitsSystemWindows.
О чём речь, и как это должно работать
Решение проблемы
Вроде бы решение простое: не работает adjustResize, значит надо реагировать на открытие клавиаруты самим. Но вот беда android не предоставляет не только высоту открывшейся клавиатуры (а она может быть разная даже для разных EditText полей), но даже сам факт её открытия или закрытия. Официального способа нет. Как же так google?
Решение конечно есть! А когда у вас появляется информация о текущей высоте клавиатуры вы можете сделать с ней что захотите: добавить padding или margin снизу для тех View, которые должны реагировать на клавиатуру и вот кастомный adjustResize готов.
Код
Для того, чтобы понять, что была открыта клавиатура, используется OnGlobalLayoutListener. Вставлять куски кода в пост не вижу смысла. Зачем писать 100 строк о том, что выражается в коде за 50?
Решение проблемы представлено в репозитории.
Присмотритесь к KeyboardHeightProvider и BaseTranslucentActivity.
Проект максимально простой, понятный, в нём нет ничего лишнего, что не относится к проблеме.
Есть пример для простого TextView, RecyclerView и ScrollView. Эта же техника была проверена и отлично работает и для NestedScrollView, NestedFragments, CoordinatorLayout, ViewPager и т.п.
P.s.: https://developer.android.com/reference/android/view/WindowInsets решает проблему с клавиатурой не хуже.