Использование BottomSheetBehavior с внутренним CoordinatorLayout
библиотека поддержки проектирования 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;
}
вопросы
излишне Слушай, я не могу сейчас это сделать. Я не могу поймать события, когда условия выполнены, и не поймать их в других случаях. На изображении ниже вы можете увидеть, что происходит со стандартным CoordinatorLayout:
лист отклоняется при прокрутке вниз на панели приложений, но не при прокрутке вниз на вложенное содержимое. Кажется, что вложенные события прокрутки не распространяются на поведение координатора;
существует также проблема с внутренней панелью приложений: вложенное содержимое прокрутки не следует за панелью приложений, когда она сворачивается..

я установил a пример проекта на github что показывает эти проблемы.
просто чтобы быть ясным, желаемое поведение:
правильное поведение панелей приложений / видов прокрутки внутри листа;
когда лист развернут, он может свернуться прокрутите вниз, но только если внутренняя панель приложений также полностью расширена. Прямо сейчас он рушится без отношения к состоянию панели приложений, и только если вы перетащите панель приложений;
когда лист свернут, прокрутка вверх жесты будут расширять его (без эффекта на внутренней панели приложений).
пример из приложения Контакты (который, вероятно, не использует BottomSheetBehavior, но это то, что я хочу):

6 ответов:
Я наконец-то выпустил свою реализацию. Найди его на Github или непосредственно из jcenter:
compile 'com.otaliastudios:bottomsheetcoordinatorlayout:1.0.0’все, что вам нужно сделать-это с помощью
BottomSheetCoordinatorLayoutкак корневой вид для вашего нижнего листа. Он автоматически раздувает рабочее поведение для себя, поэтому не беспокойтесь об этом.Я использую это в течение длительного времени, и он не должен иметь проблем прокрутки, поддерживает перетаскивание на ABL и т. д.
Я просто следил за тем, как вы задали вышеуказанный вопрос, и придумал решение, которое может потребовать больше объяснений.Пожалуйста, следуйте примеру кода и интегрировать дополнительную часть в xml, чтобы сделать его вести себя как BottomSheeet поведение
<CoordinatorLayout> <AppBarLayout> <Toolbar app:layout_collapseMode="pin"> </Toolbar> </AppBarLayout> <NestedScrollView app:layout_behavior=“@string/bottom_sheet_behavior” > <include layout="@layout/items" /> </NestedScrollView> <!-- Bottom Sheet --> <BottomSheetCoordinatorLayout> <AppBarLayout <CollapsingToolbarLayout"> <ImageView /> <Toolbar /> </CollapsingToolbarLayout> </AppBarLayout> <NestedScrollView"> <include layout="@layout/items" /> </NestedScrollView> </BottomSheetCoordinatorLayout> </CoordinatorLayout>Примечание : решение, которое работало для меня, уже объяснено в последнем комментарии вашего вопроса
лучше explantion : https://github.com/laenger/BottomSheetCoordinatorLayout
Если первый ребенок
nestedscrollэто будет происходить некоторые другие проблемы. Это решение исправлено моя проблема я надеюсь также исправить вашу.<CoordinatorLayout app:layout_behavior=“@string/bottom_sheet_behavior”> <AppBarLayout> <CollapsingToolbarLayout> <ImageView /> </CollapsingToolbarLayout> </AppBarLayout> </LinearLayout> <NestedScrollView> <LinearLayout> < Content ... /> </LinearLayout> </NestedScrollView> </LinearLayout> </CoordinatorLayout>
старайтесь не использовать
NestedScrollViewСLinearLayout, это вызывает проблемы в моем приложении тоже. Просто используйте толькоLinearLayoutвместо этого, отлично работает для меня.попробуйте следующее:
<CoordinatorLayout app:layout_behavior=“@string/bottom_sheet_behavior”> <AppBarLayout> <CollapsingToolbarLayout> <ImageView /> </CollapsingToolbarLayout> </AppBarLayout> <LinearLayout> <!--don't forget to addd this line--> app:layout_behavior="@string/appbar_scrolling_view_behavior"> < Content ... /> </LinearLayout>
Я следил за первоначальным тестовым проектом GitHub laenger по этой проблеме, и я рад поделиться с вами решением для некоторых из его проблем, так как мне тоже нужно было это поведение в моем приложении.
это решение его вопроса : панель инструментов иногда рушится слишком рано
чтобы предотвратить это, вам нужно создать свой собственный
AppBarLayout.Behavior, так как это когда вы прокручиваете вверх, все еще перетаскивая, чтоAppBarLayout.behaviorполучает движение прокрутки. Нам нужно определить, если его в STATE_DRAGGING и просто вернитесь, чтобы избежать преждевременного скрытия / сворачивания панели инструментов.public class CustomAppBarLayoutBehavior extends AppBarLayout.Behavior { private CoordinatorLayoutBottomSheetBehavior behavior; public CustomAppBarLayoutBehavior() { } public CustomAppBarLayoutBehavior(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes) { behavior = CoordinatorLayoutBottomSheetBehavior.from(parent); return super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes); } @Override public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed) { if(behavior.getState() == CoordinatorLayoutBottomSheetBehavior.STATE_DRAGGING){ return; }else { super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed); } } @Override public void setDragCallback(@Nullable DragCallback callback) { super.setDragCallback(callback); } }это может быть хорошим началом, как мы решаем другие вопросы:
панель инструментов не может быть свернута через перетаскивания
главный координатор макет потребляет некоторую прокрутку
Я на самом деле не хороший пользователь/анимационный человек, но hardwork иногда окупается пониманием кода, находя правильную функцию обратного вызова/переопределения для реализации.
как поведение appbarlayout
<android.support.design.widget.AppBarLayout android:id="@+id/bottom_sheet_appbar" style="@style/BottomSheetAppBarStyle" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_behavior="your.package.CustomAppBarLayoutBehavior">
макет для полного экрана макета appbar выглядит следующим образом: -
<android.support.design.widget.AppBarLayout android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="@dimen/detail_backdrop_height" android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" android:fitsSystemWindows="true"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/collapsing_toolbar" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_scrollFlags="scroll|exitUntilCollapsed" android:fitsSystemWindows="true" app:contentScrim="?attr/colorPrimary" app:expandedTitleMarginStart="48dp" app:expandedTitleMarginEnd="64dp"> <ImageView android:id="@+id/backdrop" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:fitsSystemWindows="true" app:layout_collapseMode="parallax" /> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:layout_collapseMode="pin" /> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingTop="24dp"> <android.support.v7.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="@dimen/card_margin"> <LinearLayout style="@style/Widget.CardContent" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Info" android:textAppearance="@style/TextAppearance.AppCompat.Title" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/cheese_ipsum" /> </LinearLayout> </android.support.v7.widget.CardView> <android.support.v7.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/card_margin" android:layout_marginLeft="@dimen/card_margin" android:layout_marginRight="@dimen/card_margin"> <LinearLayout style="@style/Widget.CardContent" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Friends" android:textAppearance="@style/TextAppearance.AppCompat.Title" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/cheese_ipsum" /> </LinearLayout> </android.support.v7.widget.CardView> <android.support.v7.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/card_margin" android:layout_marginLeft="@dimen/card_margin" android:layout_marginRight="@dimen/card_margin"> <LinearLayout style="@style/Widget.CardContent" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Related" android:textAppearance="@style/TextAppearance.AppCompat.Title" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/cheese_ipsum" /> </LinearLayout> </android.support.v7.widget.CardView> </LinearLayout> </android.support.v4.widget.NestedScrollView> <android.support.design.widget.FloatingActionButton android:layout_height="wrap_content" android:layout_width="wrap_content" app:layout_anchor="@id/appbar" app:layout_anchorGravity="bottom|right|end" android:src="@drawable/ic_discuss" android:layout_margin="@dimen/fab_margin" android:clickable="true"/>и после этого вы должны реализовать AppBarLayout.OnOffsetChangedListener в вашем классе и установить смещение экрана.
Comments