与自定义行为一起使用时滑动刷新布局问题

Swipe to refresh layout problem when used with custom behavior

我有一个 CoordinatorLayout,其中包含一个带有自定义 CoordinatorLayout.Behavior (item_search_button) 的视图和一个包含 NestedScrollViewSwipeRefreshLayout。 自定义视图是一个按钮,它应该在正常滚动时滚出屏幕,但应该在用户向上滚动列表时立即出现(从顶部滚动)。这按预期工作。 我的问题是 SwipeRefreshLayout 的刷新指示器出现在自定义视图 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>

但我想要它在项目之前。 我该如何解决这个问题?

CardView 有一个默认高度,这使得它出现在 RecyclerView 之上,尽管它是 CoordinatorLayout 中的第一个 child(参见 documentation有关 CoordinatorLayout 工作原理的说明)。要让 CardView 在刷新时消失在列表/进度指示器下方,您可以暂时将其高度设置为零,并在刷新完成后将其重置。

假设您在 res/values/dimens.xml

中有海拔的维度资源
<dimen name="cardview_elevation">4dp</dimen>

然后您可以通过编程方式设置海拔高度。

Java 版本:

float normalElevationInPixels = getResources().getDimensionPixelSize(R.dimen.cardview_elevation);
myCardView.setCardElevation(normalElevationInPixels);

Kotlin 版本:

val normalElevationInPixels = resources.getDimensionPixelSize(R.dimen.cardview_elevation)
myCardView.cardElevation = normalElevationInPixels

最后,我通过

的解决方法解决了我的问题
  1. 使用 onScrollListener 检查列表是否在顶部滚动 设置 translationX 如果它在顶部让指示器绘制 卡片视图。
  2. 使用setProgressViewOffset()增加偏移并绘制 在 cardview 下方以避免令人讨厌的闪烁效果。

适合我...