Гибкий тулбар

Это будет инструкция 📄 для создания гибкого тулбара, внешний вид которого зависит от состояния списка.

Сделаем демонстрационное приложение для Android. Будем работать в проекте с одним Activity. Для начала нужно создать список. Это будет вертикальный ScrollView, в котором будет перелистываться некоторый набор View разного типа. Список обязательно должен занимать весь экран.

Далее создадим условия, при которых тулбар будет находиться над списком. Для этого отредактируем вёрстку:

<FrameLayout ...>
<ScrollView>...</ScrollView>
<FrameLayout>...</FrameLayout>
</FrameLayout>

Сейчас тулбар просто перекрывает верхнюю часть нашего списка и мешает видеть 👀 данные. Но если мы добавим к нашему ScrollView отступ сверху равный высоте 📐 тулбара и обязательно установим свойство clipToPadding в false (это необходжимо, что бы та часть что отсутупает тоже перелистывалась), тогда тулбар будет перекрывать только ту часть, которая не содержит данных. А данные в нашем списке будут начинать отрисовываться 🎨 всегда с той точки, где заканчивает отрисовываться 🎨 тулбар (при максимальном пролистывании в начало).

Это уже можно жёстко закрепить в нашём коде.

Сейчас тулбар никак не реагирует 😕 на изменение состояния списка. Сделаем высоту 📐 тулбара зависимой от положения на экране начала списка. Для этого необходимо получать информацию 📢 о состоянии пролистывания списка.

Это можно сделать использовав метод getScrollY(). Для вертикального списка мы получим значение в пикселях — насколько пролистан список. То есть в самом верху будет значение 0, а в самом низу значение — высота 📐 всего содержимого списка вычесть высоту 📐 ScrollView. Поэтому, если высота 📐 содержимого меньше чем высота 📐 ScrollView, то список перелистываться не будет. А теперь всё что нам нужно сделать — это считывать значение при каждом событии изменения состояния пролистывания списка.

Для того чтобы быть в курсе каждый раз, когда перелистывается список мы сделаем небольшое дополнение к ScrollView. Предоставляемые по умолчанию возможности не всегда 😢 гарантированно работают на разных версиях api Adnroid sdk. Создадим класс, который гарантированно будет оповещать 📢 нас об этом событии.

Для этого мы переопределили метод onScrollChanged класса View

Теперь договоримся что наш тулбар будет изменять значение высоты 📐 от максимального toolbarMaxHeight до минимального toolbarMinHeight. Таким образом, слушая событие перелистывания, можно получить число от 0 до 1, которое будет говорить о том как должен будет измениться тулбар от минимальной высоты 📐 до максимальной.

Изменения в классе MainActivity

Сейчас мы получили всё необходимое. Каждый раз, когда происходит перелистывание, в метод setToolbarSize подаётся число от 0 до 1. Теперь можно разнообразить тулбар различными View и относительно этого числа изменять их отображение 🎨 — размер 📐, положение, прозрачность и так далее. В следующей статье мы добавим в тулбар картинку и текст.

Исходный код.