HideBottomViewOnScrollBehavior 不适用于 recyclerview 项目 expand/collapse

HideBottomViewOnScrollBehavior not working on recyclerview item expand/collapse

我试图在向下滚动时隐藏文本视图并在向上滚动时显示它在我有 10 或 15 之类的项目时工作正常但如果我有较少的项目则工作不一样

recyclerview 中,我有 expanded/collapse 功能,所以有时不一样

textview 不是 hiding/visible 有时我不明白我将这一行添加到我想要 hide/show 滚动

的视图中
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"

XML

<androidx.coordinatorlayout.widget.CoordinatorLayout
        android:id="@+id/lnMain"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@mipmap/bg"
        tools:context=".tab.history.view.HistoryFragment">

        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/mAppBarLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:elevation="0dp">

            <RelativeLayout
                android:id="@+id/lnActionBar"
                android:layout_width="match_parent"
                android:layout_height="?android:attr/actionBarSize"
                android:background="@color/colorPrimary">

                <TextView
                    android:id="@+id/tvtitle"
                    style="@style/fontMedium"
                    android:layout_width="wrap_content"
                    android:layout_height="?android:attr/actionBarSize"
                    android:layout_centerHorizontal="true"
                    android:gravity="center_vertical"
                    android:text="@string/beacon"
                    android:textColor="@color/white"
                    android:textSize="@dimen/header_font_size" />

            </RelativeLayout>

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

       
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rvBeacon"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="false"
        android:overScrollMode="never"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        android:paddingBottom="@dimen/_40sdp"
        android:scrollbars="none"
        android:visibility="visible"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        tools:itemCount="10"
        tools:listitem="@layout/raw_beacon" />

<TextView
            android:id="@+id/btnBack"
            style="@style/fontBold"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="@dimen/_10sdp"
            android:layout_marginBottom="@dimen/_20sdp"
            android:background="@drawable/background_button_yellow_20dp"
            android:contentDescription="@string/back_button"
            android:drawableStart="@drawable/ic_back"
            android:layout_gravity="bottom|center_horizontal"
            android:drawablePadding="@dimen/_5sdp"
            android:gravity="center"
            android:padding="@dimen/_10sdp"
            android:text="@string/back_to_search"
            android:textColor="@color/white"
            android:textSize="@dimen/button_font_size"
            android:visibility="@{!isScanning ? View.VISIBLE: View.GONE}"
            app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

这是我目前所做的,但并非每次都有效

注意:- 请注意,我有一个 recyclerview 项目可以扩展 onclick,因此滚动和文本视图必须根据

非常感谢任何帮助

自定义行为如何?

例如。

public class QuickReturnFooterBehavior extends CoordinatorLayout.Behavior<View> {

    private static final Interpolator INTERPOLATOR = new FastOutSlowInInterpolator();
    private static final long ANIMATION_DURATION = 200;

    private int dyDirectionSum;
    private boolean isShowing;
    private boolean isHiding;
    private boolean isNeedOption = true;

    public boolean isNeedOption() {
        return isNeedOption;
    }

    public void setNeedOption(boolean needOption) {
        isNeedOption = needOption;
    }

    public QuickReturnFooterBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View directTargetChild, @NonNull View target, int axes, int type) {
        return axes == ViewCompat.SCROLL_AXIS_VERTICAL;
    }

    @Override
    public void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View target, int dx, int dy, @NonNull int[] consumed, int type) {
        // scroll chhange up and down
        if (isNeedOption) {
            showView(child);
        } else {
            if (dy > 0 && dyDirectionSum < 0
                    || dy < 0 && dyDirectionSum > 0) {
                child.animate().cancel();
                dyDirectionSum = 0;
            }

            dyDirectionSum += dy;

            if (dyDirectionSum > child.getHeight()) {
                hideView(child);
            } else if (dyDirectionSum < -child.getHeight()) {
                showView(child);
            }

        }

    }

    private void hideView(final View view) {
        if (isHiding || view.getVisibility() != View.VISIBLE) {
            return;
        }

        ViewPropertyAnimator animator = view.animate()
                .translationY(view.getHeight())
                .setInterpolator(INTERPOLATOR)
                .setDuration(ANIMATION_DURATION);

        animator.setListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animator) {
                isHiding = true;
            }

            @Override
            public void onAnimationEnd(Animator animator) {
                isHiding = false;
                view.setVisibility(View.INVISIBLE);
            }

            @Override
            public void onAnimationCancel(Animator animator) {
                // show when cancle
                isHiding = false;
                showView(view);
            }

            @Override
            public void onAnimationRepeat(Animator animator) {
                // no-op
            }
        });

        animator.start();
    }

    private void showView(final View view) {
        if (isShowing || view.getVisibility() == View.VISIBLE) {
            return;
        }
        ViewPropertyAnimator animator = view.animate()
                .translationY(0)
                .setInterpolator(INTERPOLATOR)
                .setDuration(ANIMATION_DURATION);

        animator.setListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animator) {
                isShowing = true;
                view.setVisibility(View.VISIBLE);
            }

            @Override
            public void onAnimationEnd(Animator animator) {
                isShowing = false;
            }

            @Override
            public void onAnimationCancel(Animator animator) {
                // show when cancle
                isShowing = false;
                hideView(view);
            }

            @Override
            public void onAnimationRepeat(Animator animator) {
                // no-op
            }
        });

        animator.start();
    }
}

更新:检查可以在行为中滚动

child.canScrollVertically(1)  // "Top of list"
child.canScrollVertically(-1)  // "End of list"

**更新:添加 setter 和 getter **

private boolean isNeedOption = true;

我不知道为什么 HideBottomViewOnScrollBehavior 对你不起作用

app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"

可能是因为你有一个 expand/collapse 功能,因为你只有 recyclerview only in screen 所以你也可以通过添加 Custom ScrollListener

来执行这个任务

MyRecyclerScroll class

public abstract class MyRecyclerScroll extends RecyclerView.OnScrollListener {
    private static final float HIDE_THRESHOLD = 100;
    private static final float SHOW_THRESHOLD = 50;

    int scrollDist = 0;
    private boolean isVisible = true;

    //    We dont use this method because its action is called per pixel value change
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);

        //  Check scrolled distance against the minimum
        if (isVisible && scrollDist > HIDE_THRESHOLD) {
            //  Hide fab & reset scrollDist
            hide();
            scrollDist = 0;
            isVisible = false;
        }
        //  -MINIMUM because scrolling up gives - dy values
        else if (!isVisible && scrollDist < -SHOW_THRESHOLD) {
            //  Show fab & reset scrollDist
            show();

            scrollDist = 0;
            isVisible = true;
        }

        //  Whether we scroll up or down, calculate scroll distance
        if ((isVisible && dy > 0) || (!isVisible && dy < 0)) {
            scrollDist += dy;
        }

    }


    public abstract void show();

    public abstract void hide();
}

Activity/Fragment

binding.rvBeacon.addOnScrollListener(object : MyRecyclerScroll() {
            override fun show() {
                binding.btnBack.animate().translationY(0f).setInterpolator(DecelerateInterpolator(2f)).start()
            }

            override fun hide() {
                binding.btnBack.animate().translationY(binding.btnBack.getHeight() + 60f)
                    .setInterpolator(AccelerateInterpolator(2f)).start()
            }
        })

您可以根据需要更改动画、延迟和边距

有关详细信息,请参阅此 blog

注意:如果你的recyclerview在scrollview里面,它将不起作用