Библиотека поддержки дизайна 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()
следует использовать для кражи событий у родителя в некоторых условиях:- when the
AppBarLayout
offset is > 0 - когда смещение
AppBarLayout
== 0, но мы прокручиваем вверх (подумайте об этом на секунду, и вы увидите)
- when the
первое условие можно получить, установив
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; }
Проблемы
Излишне говорить, что я не могу сделать эту работу прямо сейчас. Я не умею ловить события при выполнении условий и не ловить их в других случаях. На изображении ниже вы можете увидеть, что происходит со стандартным CoordinatorLayout:
Лист закрывается, если вы прокручиваете вниз панель приложений, но не прокручиваете вниз вложенный контент. Кажется, что события вложенной прокрутки не распространяются на поведение координатора;
Также есть проблема с внутренней панелью приложений: содержимое вложенной прокрутки не следует за панелью приложений, когда она сворачивается.
Я установил пример проекта на github, который показывает эти проблемы.
Просто чтобы быть ясным, желаемое поведение:
Корректное поведение панелей приложений/прокрутки внутри листа;
Когда лист развернут, он может свернуться при прокрутке вниз, но только если внутренняя панель приложения также полностью развернута. Прямо сейчас он рушится независимо от состояния панели приложений, и только если вы перетаскиваете панель приложений;
Когда лист свернут, жесты прокрутки вверх расширят его (без влияния на внутреннюю панель приложений).
Пример из приложения для контактов (которое, вероятно, не использует BottomSheetBehavior, но это то, что я хочу):
app:layout_behavior="@string/appbar_scrolling_view_behavior"
- person sakiM   schedule 28.03.2016CoordinatorLayout
в настоящее время возможно. Может быть, взгляните на Plaid ElasticDragDismissFrameLayout. - person Markus Rubey   schedule 28.03.2016CoordinatorLayout
с возможностью прокрутки для детей и слегка измененныйBottomSheetBehavior
. Взгляните на эту фиксацию, чтобы увидеть мои ключевые изменения. Вы найдете гифки, иллюстрирующие, что уже работает, а что нет. - person laenger   schedule 25.11.2016