Макет координатора — свертывание взаимодействия с содержимым с представлением переработчика

схема

Как показано на рисунке, я хочу, чтобы мои 2 представления (представление переработчика и сворачивающееся содержимое) реагировали только на среднюю панель захвата (например, это может быть макет с ограничением высоты 50dp). Перемещение этой панели должно свернуть верхнюю часть — и сделать recyclerview меняет свою высоту. Полоса не должна двигаться ниже содержимого верхней части. Представление Recycler должно иметь возможность прокручиваться независимо все время.

Как сделать, чтобы только ограниченная область реагировала на сенсорные события? Как сделать так, чтобы высота recyclerview зависела от положения захвата?

Теперь в моем случае сворачивающаяся часть скрывается сразу после того, как я начинаю прокручивать recyclerview.

Если информации недостаточно, я добавлю то, что требуется.

Код:

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/activityToDo"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".ui.ToDoActivity">

    <com.google.android.material.appbar.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

        <com.google.android.material.appbar.CollapsingToolbarLayout
                android:id="@+id/collapsingToolbar"
                app:layout_scrollFlags="scroll|enterAlways"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">


            <androidx.constraintlayout.widget.ConstraintLayout
                    app:layout_collapseMode="parallax"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">

                <EditText
                        android:hint="Note title"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:id="@+id/noteTitle"
                        app:layout_constraintStart_toStartOf="parent"
                        android:layout_marginStart="10dp"
                        app:layout_constraintEnd_toStartOf="@+id/guideline"
                        android:layout_marginEnd="10dp"
                        android:layout_marginTop="15dp"
                        android:textSize="15sp"
                        android:inputType="text" app:layout_constraintTop_toTopOf="parent"/>
                <EditText
                        android:hint="Note priority"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:id="@+id/notePriority"
                        app:layout_constraintEnd_toEndOf="parent"
                        android:layout_marginEnd="10dp"
                        app:layout_constraintStart_toStartOf="@+id/guideline"
                        android:layout_marginStart="10dp"
                        android:layout_marginTop="15dp"
                        android:textSize="15sp"
                        android:inputType="number" app:layout_constraintTop_toTopOf="parent"/>

            <androidx.constraintlayout.widget.Guideline
                    android:orientation="vertical"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    app:layout_constraintGuide_begin="197dp"
                    android:id="@+id/guideline"/>

                <EditText
                        android:hint="Note description"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:id="@+id/noteDescription"
                        app:layout_constraintEnd_toEndOf="parent"
                        android:layout_marginEnd="10dp"
                        app:layout_constraintStart_toStartOf="parent"
                        android:layout_marginStart="10dp"
                        app:layout_constraintTop_toBottomOf="@+id/notePriority"
                        android:layout_marginTop="20dp"
                        android:textSize="15sp"/>
                <Button
                        android:text="Save"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:id="@+id/saveButton"
                        app:layout_constraintStart_toStartOf="parent"
                        android:layout_marginStart="10dp"
                        app:layout_constraintEnd_toStartOf="@+id/guideline" android:layout_marginEnd="10dp"
                        android:layout_marginBottom="20dp" app:layout_constraintBottom_toBottomOf="parent"
                        android:layout_marginTop="10dp" app:layout_constraintTop_toBottomOf="@+id/noteDescription"/>
                <Button
                        android:text="Clear"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:id="@+id/clearButton"
                        app:layout_constraintEnd_toEndOf="parent"
                        android:layout_marginEnd="10dp" app:layout_constraintStart_toStartOf="@+id/guideline"
                        android:layout_marginStart="10dp" android:layout_marginBottom="20dp"
                        app:layout_constraintBottom_toBottomOf="parent" android:layout_marginTop="10dp"
                        app:layout_constraintTop_toBottomOf="@+id/noteDescription"/>

            </androidx.constraintlayout.widget.ConstraintLayout>



        </com.google.android.material.appbar.CollapsingToolbarLayout>

        <TextView
                android:text="All notes"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>

    </com.google.android.material.appbar.AppBarLayout>


    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">

    <androidx.recyclerview.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/allNotesRecyclerView"
            android:layout_marginStart="8dp"
            app:layout_constraintTop_toTopOf="@id/collapsingToolbar"
            android:layout_marginTop="16dp"
            android:textSize="15sp"/>

    </LinearLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Репозиторий GitHub




Ответы (3)


в моем случае так: добавьте app:layout_behavior="@string/appbar_scrolling_view_behavior" в свой recyclerview и посмотрите мой CollapsingToolbarLayout и мою панель инструментов

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/coordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".myactivity.DetailWisataActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/app_bar_detail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapse_toolbar_detail"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:fitsSystemWindows="true"
            app:contentScrim="?colorPrimary"
            app:expandedTitleGravity="center_horizontal|bottom"
            app:layout_scrollFlags="scroll|snap|exitUntilCollapsed">

            <ImageView
                android:id="@+id/img_bg_detail"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:contentDescription="@string/app_name"
                android:scaleType="centerCrop"
                android:src="@drawable/bg_beach"
                app:layout_collapseMode="pin"
                tools:targetApi="m" />

            <View
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@color/colorTransparantBlackLow" />

            <ProgressBar
                android:id="@+id/progress_detail"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center" />

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar_detail"
                android:layout_width="match_parent"
                android:layout_height="@dimen/actionBarSizeLow"
                android:theme="@style/ThemeOverlay.AppCompat.Light"
                app:layout_collapseMode="pin"
                app:title="@string/info_wisata" />
        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>

   ............Your recyclerview here.......

    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
</androidx.coordinatorlayout.widget.CoordinatorLayout>

и удалите свой Linearlayout.

person im-o    schedule 19.08.2019
comment
Точно такой же результат, как у меня. Не решает мою проблему - person Pawel Muniak; 20.08.2019

Сначала удалите LinearLayout из списка родителей recyclerview и попробуйте следующее:

 <androidx.coordinatorlayout.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">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_scrollFlags="scroll|exitUntilCollapsed">

            <!-- HEADER -->
            <RelativeLayout
                ...
                app:layout_collapseMode="parallax">
                .....
            </RelativeLayout>

            <androidx.appcompat.widget.Toolbar
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin" />

        </com.google.android.material.appbar.CollapsingToolbarLayout>

       <!-- IF YOU WANT TO KEEP "Choose Item" always on top of the RecyclerView, put this TextView here
        <TextView
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="bottom"
             android:text="choose item" />
       -->
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

  </androidx.coordinatorlayout.widget.CoordinatorLayout>

Ответ на тот же вопрос: Ссылка

person Jamil Hasnine Tamim    schedule 02.02.2020

В новейшей версии Android Studio (4.0 Canary 9) вы можете использовать новый тип макета MotionLayout для перехода между различными ConstraintLayouts. Самое простое решение (ниже) не обязательно позволит вам изменить высоту RecyclerView на любую, которую вы хотите, но вы можете плавно переходить между двумя разными макетами, когда пользователь проводит пальцем вверх или вниз.

Короче говоря, вы бы сделали следующее:

  1. В файле build.gradle (Module: app) добавьте следующую строку:

    implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta4'

  2. Создайте новый файл макета ConstraintLayout, который определяет, как все ваши представления должны быть расположены в начале.

  3. Преобразуйте этот ConstraintLayout в MotionLayout, используя контекстное меню в редакторе макетов
    введите здесь описание изображения
  4. В редакторе MotionLayout добавьте ограничения для каждого вида в макетах «начало» и «конец» введите здесь описание изображения

  5. В новом XML-файле MotionScene, который был добавлен в папку XML в папке res, отредактируйте тег, чтобы он выглядел следующим образом:

<Transition
      motion:constraintSetEnd="@+id/end"
      motion:constraintSetStart="@id/start"
       >
       <OnSwipe               
                app:touchAnchorSide="top"
                motion:touchAnchorId="@id/YOUR_GRIP_VIEW"
                motion:dragDirection="dragUp" />
           <KeyFrameSet>
           </KeyFrameSet>
 </Transition>

* В MotionLayout Codelab указано использовать app:touchAnchorID вместо motion:touchAnchorId, но у меня это не сработало *

Теперь, когда вы проводите пальцем вверх или вниз, MotionLayout может переходить между состояниями.

person Joe Muller    schedule 02.02.2020