Search code examples
androidandroid-coordinatorlayoutswiperefreshlayout

Swipe to refresh layout problem when used with custom behavior


I have a CoordinatorLayout which contains a view with a custom CoordinatorLayout.Behavior (item_search_button) and a SwipeRefreshLayout containing a NestedScrollView. The custom view is a button which should scroll out of the screen with the normal scrolling but should appear (scroll from top) as soon as the user scrolls up the list. This works as expected. My problem is that the refresh indicator of the SwipeRefreshLayout appears behind the custom view item_search_button.

 <android.support.design.widget.CoordinatorLayout
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/toolbar_startpage"
        app:snackbar="@{offlineSnackbarVM.snackbarData}">

        <include
            layout="@layout/item_search_button"
            app:vm="@{searchButtonVM}"/>

        <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/swipeRefreshLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            app:refreshing="@{reloadVM.refreshInProgress}">

            <android.support.v4.widget.NestedScrollView
                android:id="@+id/nestedView"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <LinearLayout
                    android:id="@+id/elementsContainer"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    android:paddingTop="@dimen/spacing_48"/>

            </android.support.v4.widget.NestedScrollView>

        </android.support.v4.widget.SwipeRefreshLayout>

    </android.support.design.widget.CoordinatorLayout>

item_search_button.xml:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data class="SearchButtonBinding">

    <variable
        name="viewmodel"
        type="vm.SearchButtonVM"/>

</data>
 <android.support.v7.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:layout_behavior="behaviors.ScrollSnapBehavior"
    android:layout_margin="@dimen/spacing_8"
    android:onClick="@{() -> vm.openSearch()}">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="8dp"
            android:layout_marginRight="8dp"
            android:ellipsize="end"
            android:maxLines="1"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toRightOf="@+id/leftIcon"
            app:layout_constraintRight_toLeftOf="@+id/rightIcon"
            app:layout_constraintTop_toTopOf="parent"/>

    </android.support.constraint.ConstraintLayout>

</android.support.v7.widget.CardView>
</layout>

enter image description here

But I want it before the item. How can I solve this?


Solution

  • Finally, I solved my problem with a workaround by

    1. Using onScrollListener to check if the list is scolled at top and set translationX if it is on top to let the indicator paint over the cardview.
    2. Using setProgressViewOffset() to increase the offset and paint it below the cardview to avoid a nasty flicker effect.

    Works for me...