Принятый ответ Никиты имеет правильную идею, но имеет две проблемы:
Предложенная формула заполнения верна только тогда, когда нижний лист полностью раскрыт, потому что параметр slideOffset, предоставленный в качестве аргумента для обратного вызова onSlide, пропорционален разнице между высотой просмотра и полной высотой нижнего листа, а не просто на полную высоту
Заполнение не относится к быстрой полосе прокрутки в окне повторного просмотра, которая продолжает расширяться под нижним листом. Маржа, с другой стороны, ведет себя так, как задумано.
Вот реализация Kotlin, которая учитывает эти два исправления:
val behavior = BottomSheetBehavior.from(constraintLayout)
behavior.setBottomSheetCallback(object : BottomSheetCallback() {
override fun onSlide(bottomSheet: View, slideOffset: Float) {
val margin = behavior.peekHeight + (bottomSheet.height - behavior.peekHeight) * slideOffset
recyclerview.updateLayoutParams<FrameLayout.LayoutParams> { bottomMargin = margin.toInt() }
}
override fun onStateChanged(bottomSheet: View, newState: Int) { /* Nothing to do */ }
})
Тип LayoutParams, на который ссылаются, должен быть изменен в соответствии с родителем RecyclerView в вашем собственном макете.
Обратите внимание, что нижнее поле RecyclerView должно быть установлено равным высоте просмотра нижнего листа в XML-формате макета, чтобы получить правильный макет при загрузке действия до того, как произойдет скольжение.
Приведенный выше пример относится к нижнему листу, который нельзя скрыть, что означает, что аргумент slideOffset имеет значение только от 0 до 1.
Для скрываемого нижнего листа следует использовать другую формулу, когда значение параметра slideOffset находится в диапазоне от -1 до 0: behavior.peekHeight * (1 + slideOffset)