当我们上下滚动 recyclerView 时隐藏和显示 viewgroup

Shr*_*jan 5 android

我想在向下滚动时隐藏视图组,并在recyclerview.

这是我的代码,其中rvSearchItemsRecyclerview,并且rlSearchRelative Layout我想要隐藏和显示的代码:

rvSearchItems.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        if (dy >= 0) {
            if (rlSearch.getVisibility() != View.GONE)
                rlSearch.setVisibility(View.GONE);
        } else if(dy<-5) {
            if (rlSearch.getVisibility() != View.VISIBLE)
                rlSearch.setVisibility(View.VISIBLE);
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

这里的主要问题是当我们快速滚动时它工作正常。如果我们缓慢滚动,它会闪烁多次。

Kat*_*thi 5

我利用来coordinateLayout实现这种行为

而不是LinerLayout我想CardView在滚动时显示/隐藏(您可以在您的情况下recyclerView使用任何)ViewGroup

基本上这个答案是通过使用FABAppBarLayout行为来实现的,如Iin LakeFAB 行为中描述的那样

CardViewAwareScrollingViewBehavior :: *

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.view.ViewCompat;
import android.support.v7.widget.CardView;
import android.util.AttributeSet;
import android.view.View;

import java.util.List;

public class CardViewAwareScrollingViewBehavior extends AppBarLayout.ScrollingViewBehavior {
    int mAnimState = ANIM_STATE_NONE;
    static final int ANIM_STATE_NONE = 0;
    static final int ANIM_STATE_HIDING = 1;
    static final int ANIM_STATE_SHOWING = 2;
    static final int SHOW_HIDE_ANIM_DURATION = 200;
    public CardViewAwareScrollingViewBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
        return super.layoutDependsOn(parent, child, dependency) ||
                dependency instanceof CardView;
    }

    @Override
    public boolean onStartNestedScroll(final CoordinatorLayout coordinatorLayout, final View child,
            final View directTargetChild, final View target, final int nestedScrollAxes) {
        // Ensure we react to vertical scrolling
        return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL
                || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
    }

    @Override
    public void onNestedScroll(final CoordinatorLayout coordinatorLayout, final View child,
            final View target, final int dxConsumed, final int dyConsumed,
            final int dxUnconsumed, final int dyUnconsumed) {
        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
        if (dyConsumed > 0) {
            // User scrolled down -> hide the CardView
            List<View> dependencies = coordinatorLayout.getDependencies(child);
            for (View view : dependencies) {
                if (view instanceof CardView) {
                   hide( ((CardView) view));

                }
            }
        } else if (dyConsumed < 0) {
            // User scrolled up -> show the CardView
            List<View> dependencies = coordinatorLayout.getDependencies(child);
            for (View view : dependencies) {
                if (view instanceof CardView) {
                    show((CardView) view);
                }
            }
        }
    }

    void show(final View mView) {
        if (isOrWillBeShown(mView)) {
            // We either are or will soon be visible, skip the call
            return;
        }

        mView.animate().cancel();

        if (shouldAnimateVisibilityChange(mView)) {
            mAnimState = ANIM_STATE_SHOWING;

            if (mView.getVisibility() != View.VISIBLE) {
                // If the view isn't visible currently, we'll animate it from a single pixel
                mView.setAlpha(0f);
                mView.setScaleY(0f);
                mView.setScaleX(0f);
            }

            mView.animate()
                    .scaleX(1f)
                    .scaleY(1f)
                    .alpha(1f)
                    .setDuration(SHOW_HIDE_ANIM_DURATION)
                   // .setInterpolator(AnimationUtils.LINEAR_OUT_SLOW_IN_INTERPOLATOR)
                    .setListener(new AnimatorListenerAdapter() {
                        @Override
                        public void onAnimationStart(Animator animation) {
//                            mView.internalSetVisibility(View.VISIBLE, false);
                            mView.setVisibility(View.VISIBLE);
                        }

                        @Override
                        public void onAnimationEnd(Animator animation) {
                            mAnimState = ANIM_STATE_NONE;

                        }
                    });
        } else {
//            mView.internalSetVisibility(View.VISIBLE, fromUser);
            mView.setVisibility(View.VISIBLE);
            mView.setAlpha(1f);
            mView.setScaleY(1f);
            mView.setScaleX(1f);

        }
    }

    void hide(final View mView) {
        if (isOrWillBeHidden(mView)) {
            // We either are or will soon be hidden, skip the call
            return;
        }

        mView.animate().cancel();

        if (shouldAnimateVisibilityChange(mView)) {
            mAnimState = ANIM_STATE_HIDING;

            mView.animate()
                    .scaleX(0f)
                    .scaleY(0f)
                    .alpha(0f)
                    .setDuration(SHOW_HIDE_ANIM_DURATION)
//                    .setInterpolator(AnimationUtils.FAST_OUT_LINEAR_IN_INTERPOLATOR)
                    .setListener(new AnimatorListenerAdapter() {
                        private boolean mCancelled;

                        @Override
                        public void onAnimationStart(Animator animation) {
//                            mView.internalSetVisibility(View.VISIBLE, fromUser);
                            mView.setVisibility(View.VISIBLE);
                            mCancelled = false;

                        }

                        @Override
                        public void onAnimationCancel(Animator animation) {
                            mCancelled = true;
                        }

                        @Override
                        public void onAnimationEnd(Animator animation) {
                            mAnimState = ANIM_STATE_NONE;

                            if (!mCancelled) {
//                                mView.internalSetVisibility(fromUser ? View.GONE : View.INVISIBLE,
//                                        fromUser);
                                mView.setVisibility(View.GONE);
//                                if (listener != null) {
//                                    listener.onHidden();
//                                }
                            }
                        }
                    });
        } else {
            // If the view isn't laid out, or we're in the editor, don't run the animation
//            mView.internalSetVisibility(true ? View.GONE : View.INVISIBLE, fromUser);
            mView.setOverScrollMode(View.GONE);
//            if (listener != null) {
//                listener.onHidden();
//            }
        }
    }



    boolean isOrWillBeShown(View mView) {
        if (mView.getVisibility() != View.VISIBLE) {
            // If we not currently visible, return true if we're animating to be shown
            return mAnimState == ANIM_STATE_SHOWING;
        } else {
            // Otherwise if we're visible, return true if we're not animating to be hidden
            return mAnimState != ANIM_STATE_HIDING;
        }
    }

    private boolean shouldAnimateVisibilityChange(View mView) {
        return ViewCompat.isLaidOut(mView) && !mView.isInEditMode();
    }

    boolean isOrWillBeHidden(View mView) {
        if (mView.getVisibility() == View.VISIBLE) {
            // If we currently visible, return true if we're animating to be hidden
            return mAnimState == ANIM_STATE_HIDING;
        } else {
            // Otherwise if we're not visible, return true if we're not animating to be shown
            return mAnimState != ANIM_STATE_SHOWING;
        }
    }


}
Run Code Online (Sandbox Code Playgroud)

使用 CardViewAwareScrollingViewBehavior 的 CustomerCardView :: *

import android.content.Context;
import android.support.design.widget.CoordinatorLayout;
import android.support.v7.widget.CardView;
import android.util.AttributeSet;

@CoordinatorLayout.DefaultBehavior(CardViewAwareScrollingViewBehavior.class)
public class CustomerCardView extends CardView {

    public CustomerCardView(Context context) {
        super(context);
    }

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

    public CustomerCardView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


}
Run Code Online (Sandbox Code Playgroud)

并在 xml 中使用此 customCardView,如下所示

主文件

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:titleTextColor="@android:color/white">
        </android.support.v7.widget.Toolbar>
    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main"/>

</android.support.design.widget.CoordinatorLayout>
Run Code Online (Sandbox Code Playgroud)

main.xml中包含的content_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.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:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="prathap.recyclerviewsample.adapters.UI.CardViewAwareScrollingViewBehavior"
    tools:context="prathap.recyclerviewsample.MainActivity"
    tools:showIn="@layout/acitivity_main">

<!--this is out custom Cardview with custom behaviour -->

    <prathap.recyclerviewsample.CustomViews.CustomerCardView
        android:id="@+id/card_"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <ImageButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher"/>

    </prathap.recyclerviewsample.CustomViews.CustomerCardView>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_behavior="prathap.recyclerviewsample.adapters.UI.CardViewAwareScrollingViewBehavior"
        />
</android.support.design.widget.CoordinatorLayout>
Run Code Online (Sandbox Code Playgroud)

这样我们就可以让 CardView 在 recyclerView 向上滚动时隐藏,在 recycleView 向下滚动时显示。

这是我的示例截屏视频

在此输入图像描述