Прокрутка не работает с координаторомLayout + изображение параллакса + BottomSheetLayout

Введение

У меня есть активность, которая реализует общий шаблон с изображением заголовка параллакса и прокруткой содержимого с использованием CoordinatorLayout , AppBarLayout и CollapsingToolbarLayout . Мой XML-макет выглядит следующим образом:

 <android.support.design.widget.CoordinatorLayout android:fitsSystemWindows="true" android:layout_height="match_parent" android:layout_width="match_parent"> <android.support.design.widget.AppBarLayout android:fitsSystemWindows="true" android:id="@+id/appbar" android:layout_height="wrap_content" android:layout_width="match_parent" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.design.widget.CollapsingToolbarLayout android:fitsSystemWindows="true" android:layout_height="wrap_content" android:layout_width="match_parent" app:contentScrim="?attr/colorPrimary" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <TextView android:background="@color/colorAccent" android:gravity="center" android:layout_height="250dp" android:layout_width="match_parent" android:text="ParallaxImage" app:layout_collapseMode="parallax"/> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_height="?attr/actionBarSize" android:layout_width="match_parent" app:layout_collapseMode="pin" app:popupTheme="@style/AppTheme.PopupOverlay"/> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <android.support.v4.widget.NestedScrollView android:id="@+id/content" android:layout_height="match_parent" android:layout_width="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <TextView android:layout_height="wrap_content" android:layout_margin="@dimen/text_margin" android:layout_width="wrap_content" android:text="@string/large_text"/> </android.support.v4.widget.NestedScrollView> </android.support.design.widget.CoordinatorLayout> 

Как вы видите в анимации gif ниже, все работает правильно. Вы можете прокручивать весь экран из содержимого NestedScrollView а также с Toolbar или представления параллакса.

AppBarLayout + NestedScrollView

проблема

Google представил класс BottomSheetBehavior (библиотека поддержки дизайна Android 23.2 ), чтобы помочь разработчикам реализовать нижние листы . Мой xml-макет с нижним листом выглядит следующим образом:

 <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true"> <android.support.design.widget.AppBarLayout android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:fitsSystemWindows="true" android:theme="@style/AppTheme.AppBarOverlay"> <!-- ommited --> </android.support.design.widget.AppBarLayout> <android.support.v4.widget.NestedScrollView android:id="@+id/content" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior"> <!-- ommited --> </android.support.v4.widget.NestedScrollView> <LinearLayout android:id="@+id/bottomSheet" android:layout_width="match_parent" android:layout_height="400dp" android:background="@android:color/holo_blue_bright" android:orientation="vertical" app:behavior_peekHeight="?attr/actionBarSize" app:layout_behavior="android.support.design.widget.BottomSheetBehavior"> <TextView android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:gravity="center_vertical" android:paddingLeft="16dp" android:paddingRight="16dp" android:text="BottomSheetLayout" android:textColor="@android:color/white"/> <android.support.v4.widget.NestedScrollView android:id="@+id/bottomSheetContent" android:layout_width="match_parent" android:layout_height="wrap_content" android:scrollbars="vertical"> <TextView android:layout_width="match_parent" android:layout_height="400dp" android:background="@android:color/holo_green_dark" android:padding="16dp" android:text="@string/large_text" android:textColor="@android:color/white"/> </android.support.v4.widget.NestedScrollView> </LinearLayout> </android.support.design.widget.CoordinatorLayout> 

Результат выглядит так:

Введите описание изображения здесь

Как вы можете видеть, теперь я не могу прокручивать, если я начну прокручиваться из параллакса View . Прокрутка из содержимого NestedScrollView и с Toolbar работает NestedScrollView .

Вопрос

Как я могу управлять прокруткой для работы с параметром Parallax View (так же, как и в первой анимации gif)? Кажется, что BottomSheetBehavior перехватывает события касания и препятствует AppBarLayout ( AppBarLayoutBehavior ) обрабатывать свиток. Но странно, что прокрутка с Toolbar работает, и параллакс View и Toolbar являются AppBarLayout .

Solutions Collecting From Web of "Прокрутка не работает с координаторомLayout + изображение параллакса + BottomSheetLayout"

Я думаю, вы должны использовать NestedScrollView с BottomSheetBehavior , замените удар как bootemSheet!

 <android.support.v4.widget.NestedScrollView android:id="@+id/bottomSheet" android:layout_width="match_parent" android:layout_height="400dp" android:background="@android:color/holo_blue_bright" android:orientation="vertical" app:behavior_peekHeight="?attr/actionBarSize" app:layout_behavior="android.support.design.widget.BottomSheetBehavior"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:gravity="center_vertical" android:paddingLeft="16dp" android:paddingRight="16dp" android:text="BottomSheetLayout" android:textColor="@android:color/white"/> <ScrollView android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="400dp" android:background="@android:color/holo_green_dark" android:padding="16dp" android:text="@string/large_text" android:textColor="@android:color/white"/> </ScrollView> </LinearLayout> </android.support.v4.widget.NestedScrollView> 

NestedScrollView может знать, как вложить в LinearLayout панель инструментов, а не LinearLayout !

Хочу помочь !!

Вероятно, это ошибка в коде BottomSheetBehavior , потому что если вы попытаетесь отладить код CoordinatorLayout вы увидите, что при касании вашего параллакса View он будет определен как макет с BottomSheetBehavior вместо HeaderBehavior .

Таким образом, быстрое исправление, которое я нашел, – установить OnTouchListener который всегда возвращает true для вашего представления параллакса:

 View parallaxView = findViewById(R.id.parallax_view); parallaxView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return true; } }); 

Конечно, не забудьте установить android:id="@+id/parallax_view" на ваш взгляд с режимом коллапса параллакса.

Надеюсь, поможет!

попробуй это

  <LinearLayout android:id="@+id/bottomSheet" android:layout_width="match_parent" android:layout_height="400dp"> 

Изменить высоту 400dp на wrap_content

Надежда работает для вас

Я копирую вставляемый XML, который я использую. Он работает на Samsung Galaxy S3, Huawei Mate 8 и Moto, кстати, и я не пробовал эмулятор (я удалил все деловые вещи и просто добавил фиктивные виджеты).

 <?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/coordinatorlayout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true"> <android.support.design.widget.AppBarLayout android:id="@+id/appbarlayout" android:layout_width="match_parent" android:layout_height="256dp" android:theme="@style/AppTheme.AppBarOverlay" 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/AppTheme.PopupOverlay" 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:paddingBottom="16dp"> <android.support.v7.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="16dp"> <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="Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo." /> </LinearLayout> </android.support.v7.widget.CardView> <android.support.v7.widget.CardView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:layout_marginLeft="16dp" android:layout_marginRight="16dp"> <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="TITLE" android:textAppearance="@style/TextAppearance.AppCompat.Title" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="text 1" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="text 2" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="text 3" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="text 4" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="text 5" /> </LinearLayout> </android.support.v7.widget.CardView> </LinearLayout> </android.support.v4.widget.NestedScrollView> <android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" app:behavior_peekHeight="100dp" android:fitsSystemWindows="true" app:layout_behavior="android.support.design.widget.BottomSheetBehavior"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="16dp" android:background="@android:color/white" android:padding="15dp"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="BOOTOMSHEET TITLE" android:textAppearance="@style/TextAppearance.AppCompat.Title" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Button1"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="text 2" android:layout_margin="10dp"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="text 3" android:layout_margin="10dp"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="text 4" android:layout_margin="10dp"/> <FrameLayout android:layout_width="match_parent" android:layout_height="320dp" android:background="@color/colorAccent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:text="Your remaining content here" android:textColor="@android:color/white" /> </FrameLayout> </LinearLayout> </android.support.v4.widget.NestedScrollView> 

Проблема может быть решена путем перемещения NestedScrollView (или фрагмента, содержащего NestedScrollView в моем случае) за пределами CoordinatorLayout в FrameLayout и размещения фиктивного представления, где NestedScrollView был следующим:

 <FrameLayout> <CoordinatorLayout> <AppBarLayout> ... </AppBarLayout> <View android:id="@+id/bottomSheet" app:layout_behavior="android.support.design.widget.BottomSheetBehavior" /> </CoordinatorLayout> <NestedScrollView android:id="@+id/bottomSheetContent"> ... </NestedScrollView> </FrameLayout> 

Наконец, добавьте BottomSheetCallback в фиктивный вид, который переводит фактический просмотр содержимого во время скольжения:

 @Override public void onSlide(@NonNull View bottomSheet, float slideOffset) { bottomSheetContent.setTranslationY((1f - slideOffset) * bottomSheetContent.getHeight()); } 

По-видимому, это единственный способ помешать координатору Layout реагировать на (и перехватывать) любые события касания. #JustGoogleThings

Я придумал свой собственный ответ:

  • Добавьте app:layout_behavior="...AppBarLayoutCustomBehavior" в ваш appBarLayout .

  • Создайте этот класс и простирайтесь от AppBarLayout.Behavior

  • Переопределить onStartNestedScroll и onNestedFling

  • Создайте флаг scrollDenial и добавьте его к обоим методам ниже, затем вызовите super (scrollDenial && super.onStartNestedScroll …)

  • Теперь вам нужно обновить свое условие отказа на каждом onStartNestedScroll. Я сделал что-то вроде этого:

    https://gist.github.com/recoverrelax/8dd37b54910d70b5cd6a130a070c51e9

Ps. Извините, но это Котлин: p Не должно быть трудно понять. Он решил проблему bottomSheet.