увеличение и уменьшение высоты RV в зависимости от другой прокрутки RV - PullRequest
2 голосов
/ 01 марта 2020

Я хочу добиться следующего поведения -

https://ezgif.com/optimize/ezgif-6-66c61806b01c.gif

здесь он мой XML файл -

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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/fragment_marketplace_root_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="7dp">

    <LinearLayout
        android:id="@+id/fragment_marketplace_main_linear_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:focusableInTouchMode="true"
        android:orientation="vertical">

        <com.twoverte.views.ClearableAutoCompleteTextView
            android:id="@+id/fragment_marketplace_searchview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="14dp"
            android:layout_marginTop="15dp"
            android:layout_marginEnd="14dp"
            android:completionThreshold="0"
            android:hint="@string/fragment_marketplace_search_hint"
            android:iconifiedByDefault="false"
            android:inputType="text|textAutoCorrect"
            android:maxLength="25"
            android:textIsSelectable="false"
            android:textSelectHandle="@xml/empty_shape"
            tools:layout_editor_absoluteX="1dp"
            tools:layout_editor_absoluteY="1dp" />

        <TextView
            android:id="@+id/fragment_marketplace_discover_products_from_myverte_textview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="14dp"
            android:layout_marginTop="15dp"
            android:fontFamily="@font/noto_sans"
            android:text="@string/fragment_marketplace_discover_products_from_myverte"
            android:textSize="17sp" />

        <androidx.core.widget.NestedScrollView
            android:id="@+id/fragment_marketplace_vendors_nested_scrollview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp">

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/fragment_marketplace_vendors_recycler_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginStart="14dp"
                android:layout_marginEnd="14dp"
                android:orientation="horizontal"
                tools:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
                tools:listitem="@layout/fragment_marketplace_vendor_row_item" />

        </androidx.core.widget.NestedScrollView>


        <androidx.core.widget.NestedScrollView
            android:id="@+id/fragment_marketplace_featured_products_nested_scroll_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <TextView
                    android:id="@+id/fragment_marketplace_featured_products_textview"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@color/very_light_grey"
                    android:fontFamily="@font/noto_sans"
                    android:paddingStart="14dp"
                    android:paddingLeft="14dp"
                    android:paddingTop="15dp"
                    android:paddingEnd="14dp"
                    android:text="@string/fragment_marketplace_featured_products"
                    android:textSize="17sp"
                    android:visibility="gone"
                    tools:visibility="visible" />

                <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/fragment_marketplace_products_recycler_view"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_gravity="center"
                    android:background="@color/very_light_grey"
                    app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
                    tools:listitem="@layout/fragment_marketplace_products_row_item" />

                <View
                    android:id="@+id/activity_product_page_bottom_view"
                    android:layout_width="match_parent"
                    android:layout_height="70dp"
                    android:layout_marginTop="60dp"
                    android:background="@color/light_black"
                    android:visibility="gone"
                    tools:visibility="visible" />


            </LinearLayout>

        </androidx.core.widget.NestedScrollView>

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

Я пробовал ОЧЕНЬ МНОГО комбинаций с setOnScrollChangeListener и addOnScrollListener, и ничего не работает, как ожидалось.

Необходимый результат - иметь возможность увеличивать и уменьшать максимальный RV до максимума.

Уменьшение должно быть сделано при прокрутке нижнего RV вниз, в то время как увеличение выполняется при прокрутке вверх.

Если кто-то может помочь мне в этом, я буквально kiss его ног, я потратил бы столько часов, пытаясь понять, как сделать это поведение, что мне это надоело.

редактировать

необходимую анимацию -

enter image description here

1 Ответ

2 голосов
/ 04 марта 2020

Я наконец понял это. Я поделюсь кодом для файла XML в том виде, в котором он есть, а затем объясню все об этом позже.

<?xml version="1.0" encoding="utf-8"?>
<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"
    xmlns:tools="http://schemas.android.com/tools">

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

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="256dp"
            android:minHeight="132dp"
            android:fitsSystemWindows="true"
            app:titleEnabled="false"
            app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

            <View
                android:id="@+id/blue_view"
                android:layout_width="match_parent"
                android:layout_height="128dp"
                android:background="@android:color/holo_blue_bright"
                app:layout_collapseMode="pin"
                app:layout_collapseParallaxMultiplier="0"
                android:layout_gravity="top"/>

            <HorizontalScrollView
                android:id="@+id/pink_view"
                android:layout_width="match_parent"
                android:layout_height="128dp"
                app:layout_collapseMode="parallax"
                app:layout_collapseParallaxMultiplier="1"
                android:layout_gravity="bottom">

                <View
                    android:layout_width="2000dp"
                    android:minWidth="2000dp"
                    android:layout_height="match_parent"
                    android:background="@color/colorAccent"/>

            </HorizontalScrollView>

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

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

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

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Примечание. Я использовал View с разными цветами, чтобы предварительно просмотреть разные сегменты в макете. Я также использовал HorizontalScrollView, чтобы продемонстрировать что-то вроде RecyclerView, как в загруженном вами gif.


Хорошо, поэтому сначала нам нужно создать CollapsingToolbarLayout с layout_scrollFlags.

  • мы используем флаг scroll должен быть включен для всех эффектов прокрутки для вступления в силу
  • мы используем флаг snap, чтобы определить, что делать, когда только вид был частично уменьшен. Если прокрутка заканчивается и размер вида был уменьшен до менее чем 50% от исходного, тогда этот вид возвращается к исходному размеру. Если размер больше 50% от его размера, он полностью исчезнет.
  • мы используем exitUntilCollapsed вместе с minHeight, чтобы свернуть Toolbar до указанного minHeight

Мы хотим, чтобы CollapsingToolbarLayout имел:

  • layout_height, установленный на расширенную высоту Toolbar
  • minHeight установлен на свернутую высоту Toolbar

В этом случае, так как мы хотим HorizontalScrollView (pink_view) только чтобы уменьшить в высоту , мы устанавливаем для minHeight значение [ высота из blue_view + меньшее высота из pink_view]

Следовательно, поскольку blue_view останется 128dp и мы хотим, чтобы pink_view до go до 4dp, мы установим minHeight в 132dp.

Итак, вот небольшой пример. Предположим, что blue_view походит на 100dp, а pink_view изначально 100dp. Итак, вот как мы хотим, чтобы это сначала показывалось, , но когда я начинаю прокручивать , мы хотим, чтобы pink_view до go уменьшилось до 20dp, а blue_view останется на 100dp.

Следовательно, layout_height будет 200dp, а minHeight будет 120dp.


Теперь мы хотим, чтобы HorizontalScrollView или pink_view свернуть с CollapsingToolbarLayout высотой .

Итак, мы добавляем layout_collapseMode="parallax" к pink_view так, что он прокручивается вместе с CollapsingToolbarLayout.

. layout_collapseParallaxMultiplier определяет, какая часть изображения (в процентах) будет скрыта под нижним содержимым. И здесь мы хотим, чтобы это все было скрыто. Поэтому мы устанавливаем значение 1.


Тем временем мы хотим, чтобы blue_view оставался закрепленным наверху. И мы также не хотим, чтобы он был скрыт под каким-либо нижним содержимым.

Итак, мы добавляем layout_collapseMode="pin" к blue_view таким образом, что он прикрепляется к вершине CollapsingToolbarLayout.

Мы также добавляем layout_collapseParallaxMultiplier="0", чтобы он не скрывался ни под каким содержимым.


Обратите внимание, что если высота элементов превышает minHeight, CollapsingToolbarLayout будет помещен над экраном. Тогда будет казаться, что высота верхнего элемента (здесь blue_view) уменьшается в размере.


Предварительный просмотр:

enter image description here


Вот еще одна демонстрация с RecyclerView:

enter image description here

XML для вышеупомянутого RecyclerView демоверсия ниже, если кому-то интересно * и ViewHolder, мы должны изменить их размер, когда offset из AppBarLayout изменяется при прокрутке.

Это потому, что CollapsingToolbarLayout просто прокручивает элементы внутри него друг под другом вместо фактического изменения их размера.

Итак, мы должны использовать RecyclerView, называемый здесь hv_list, и AppBarLayout, называемый здесь app_bar.

val hv_list: RecyclerView = findViewById(R.id.hv_list)

val app_bar: AppBarLayout = findViewById(R.id.app_bar)

После этого нам нужно запомнить исходный размер hv_list.

val hv_original_height: Int = hv_list.layoutParams.height

Наконец, нам нужно установить OffsetChangedListener для AppBarLayout. Там мы изменим высоту RecyclerView и затем добавим нижнее поле к pu sh до только потому, что оно имеет гравитационное дно .

app_bar.addOnOffsetChangedListener(object : AppBarLayout.OnOffsetChangedListener {
    override fun onOffsetChanged(appBarLayout: AppBarLayout, i: Int) {
        hv_list.updateLayoutParams {
            this.height = hv_original_height + i
            (this as CollapsingToolbarLayout.LayoutParams).setMargins(0, 0, 0, abs(i))
        }
    }
})

Убедитесь, что ваш itemView в RecyclerView имеет высоту из match_parent

...