В библиотеке поддержки дизайна v. 23.2 представлен BottomSheetBehavior, который позволяет дочерним элементам координатора действовать как нижние листы (просмотры перетаскиваются из нижней части экрана).
Идентификатор должен иметь как представление нижнего листа, следующее представление (типичный координатор + сворачивающийся материал):
<CoordinatorLayout
app:layout_behavior="@string/bottom_sheet_behavior">
<AppBarLayout>
<CollapsingToolbarLayout>
<ImageView />
</CollapsingToolbarLayout>
</AppBarLayout>
<NestedScrollView>
<LinearLayout>
< Content ... />
</LinearLayout>
</NestedScrollView>
</CoordinatorLayout>
К сожалению, представления нижнего листа должны реализовывать вложенную прокрутку, иначе они не будут получать события прокрутки. Если вы попытаетесь выполнить основное действие, а затем загрузите это представление в качестве нижнего листа, вы увидите, что события прокрутки действуют только на "листе" бумаги с некоторым странным поведением, так как вы можете видеть, продолжаете ли вы читать.
Я уверен, что это может быть обработано путем подклассификации CoordinatorLayout или даже лучше с помощью подкласса BottomSheetBehavior. У вас есть намек?
Некоторые мысли
-
requestDisallowInterceptTouchEvent()следует использовать, чтобы украсть события у родителя в некоторых условиях:- когда смещение
AppBarLayout> 0 - когда смещение
AppBarLayoutравно == 0, но мы прокручиваем (подумаем об этом на секунду и посмотрим на вас)
- когда смещение
-
первое условие можно получить, установив
OnOffsetChangedво внутреннюю панель приложений; -
для второго требуется некоторая обработка событий, например:
switch (MotionEventCompat.getActionMasked(event)) { case MotionEvent.ACTION_DOWN: startY = event.getY(); lastY = startY; userIsScrollingUp = false; break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: userIsScrollingUp = false; break; case MotionEvent.ACTION_MOVE: lastY = event.getY(); float yDeltaTotal = startY - lastY; if (yDeltaTotal > touchSlop) { // Moving the finger up. userIsScrollingUp = true; } break; }
Вопросы
Излишне говорить, что я не могу сделать эту работу прямо сейчас. Я не могу поймать события, когда условия соблюдены, и не поймать их в других случаях. На изображении ниже вы можете увидеть, что происходит со стандартным координаторомLayout:
-
Лист отклоняется, если вы прокручиваете панель приложений, но не прокручиваете вниз вложенное содержимое. Кажется, что вложенные события прокрутки не распространяются на поведение Координатора,
-
Существует также проблема с внутренней панелью приложения: вложенное содержимое прокрутки не следует за панелью приложения, когда оно сбрасывается.
Я установил образец проекта на github, который показывает эти проблемы.
Чтобы быть ясным, желаемое поведение:
-
Корректное поведение видов приложений/прокрутки внутри листа;
-
Когда лист расширяется, он может свернуться на прокрутку вниз, но , только если внутренняя панель приложения полностью развернута.. Сейчас он рушится без учета состояния панели приложений, и только если вы перетащите панель приложения,
-
Когда лист свернут, прокручивание жестов расширит его (без влияния на внутреннюю панель приложений).
Пример из приложения контактов (который, вероятно, не использует метод BottomSheetBehavior, но это то, что я хочу):

