Custom Bottom Sheet: как это должно работать

Предисловие


Не так давно я прочитал статью о Bottom Sheet'e и, посовещавшись с коллегами, принял решение внедрить данную штуку в наше приложение. Потратив достаточно часов с целью научить Bottom Sheet выезжать в несколько шагов (like Google Maps), я осознал его тупость и ограниченность. Было найдено два решения: оборачивать всё в поток, который будет отслеживать состояние вытянутой шторки в реальном времени или же переписать некоторые методы класса BottomSheetBehavior (благо, лицензия Apache 2.0 позволяет это делать). Я выбрал второй вариант, ибо он показался мне более жизнеспособным, и сейчас, опираясь на свой опыт, я постараюсь поведать вам что из этого вышло. Надеюсь, что кому-то это пригодится. Что-ж, приступим.


Кастомизация


Я опускаю этапы создания проекта, добавление в него гугловского Bottom Sheet'a, ибо если вы читаете это, то всё вышеперечисленное уже преодолели. Нам понадобится перейти в класс BottomSheetBehavior и скопировать его содержимое в новый, нами созданный класс CustomBottomSheetBehavior. После того как скопировали, не забудьте переименовать всё, что отметится красным цветом. Также, в .xml файле нашего BottomSheet'a следует переименовать эту строку, ссылаясь на наш новый класс, должно получиться как-то так:


app:layout_behavior="com.my.custombottomsheetexample.CustomBottomSheetBehavior"

И так, мы имеем 700+ строк кода на Java, который выглядит страшно, что же с ними делать?
Для начала необходимо найти метод onViewReleased():


public void onViewReleased(@NonNull View releasedChild, float xvel, float yvel) {

        ...

}

Нам понадобится изменить всего пару строк. Находим первый if {...} и заменяем его содержимое на этот код:


if (yvel < 0.0F) {
        currentTop = releasedChild.getTop();
        if (currentTop > CustomBottomSheetBehavior.this.halfExpandedOffset) {
        top = CustomBottomSheetBehavior.this.halfExpandedOffset;
        targetState = 6;
} else {
        top = 0;
        targetState = 3;
    }
}

Теперь наш BottomSheet выдвигается в 2 этапа, останавливаясь посередине:


()


Изменение высоты


Но это ещё не всё, вы можете регулировать среднюю высоту. Для этого всё в том же классе найдите инициализацию переменной halfExpandedOffset:


this.halfExpandedOffset = this.parentHeight / 2;

При взгляде на эту строку становится понятно, что высоту мы можем настроить как нам угодно, даже в процентном соотношении. Лично я предпочёл изменить так:


this.halfExpandedOffset = this.parentHeight * 60 / 100;

()


Мой BottomSheet выдвигается на 40% от высоты основного View. На этом всё!

Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 8

    +3
    Кхм… И когда это костыли с решением в две строчки стали достойны статьи? Где история компонента, плюсы и минусы использования, особенности работы… на худой конец анализ кода с цитатами интересных мест?
      +1
      Я не ставил целью статьи подробный разбор данного компонента, к тому же, я сослался на материал по добавлению этого вью. Цель статьи — показать, как можно гибко настроить данный компонент под ваши нужды, а не рассказать «историю, плюсы и минусы». Намного лучше, чем я мог бы написать, об этом было рассказано уже во многих источниках)
      0
      Там есть BottomSheetBehavior.STATE_HALF_EXPANDED, ты придумал очередной велосипед
        0

        Да, но это не даёт возможности выдвигать bottomSheet в несколько этапов

      0
      Этой статьи мне не хватало год назад. Долгое время мучился с BottomSheetBehavior.STATE_HALF_EXPANDED. Огромное спасибо.
        0

        Очень рад, что кому-то пригодился мой опыт!

        0
        Где ты раньше был, когда мне нужно было добавить еще одно состояние в Bottom Sheet?

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

        Самое читаемое