我想在向下滚动时隐藏视图组,并在recyclerview
向上滚动时显示视图。
这是我的代码,其中rvSearchItems
是Recyclerview
,rlSearch
是Relative 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);
}
}
});
这里的主要问题是当我们快速滚动时它工作正常。如果我们慢慢滚动它会多次晃动。
答案 0 :(得分:2)
我利用coordinateLayout
来实现此行为
而不是LinerLayout
我希望在CardView
滚动时显示/隐藏recyclerView
(您可以在案例中使用任何ViewGroup
)
基本上,这些答案是使用FAB
中描述的AppBarLayout
和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;
}
}
}
行为Iin Lake来实现的。{3}}
CardViewAwareScrollingViewBehavior :: *
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);
}
}
使用CardViewAwareScrollingViewBehavior :: *
的CustomerCardView<?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>
并在xml中使用此customCardView,如下所示
<强> 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>
和 content_main.xml ,它包含在 main.xml
中Options -MultiViews
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^page/([A-Za-z0-9-_\-]+)/?$ page.php?opt=$1 [L]
有了这个,我们在recyclelerView向上滚动时显示CardView,并在recycleView向下滚动时显示。
这是我的样本截屏视频
答案 1 :(得分:1)
这是我为 Kotlin 扩展 RecyclerView 类的代码。只需将其添加到您的项目中并在 Fragment 或 Activity 中使用,如下所示:
myRecyclerView.addOnScrollHiddenView(myAnyHiddenView, resources.dpToPx(myValuedp))
........
fun RecyclerView.addOnScrollHiddenView(
hiddenView: View,
translationX: Float = 0F,
translationY: Float = 0F,
duration: Long = 200L
) {
var isViewShown = true
this.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
when{
dy> 0 && isViewShown -> {
isViewShown = false
hiddenView.animate()
.translationX(translationX)
.translationY(translationY)
.duration = duration
}
dy < 0 && !isViewShown ->{
isViewShown = true
hiddenView.animate()
.translationX(0f)
.translationY(0f)
.duration = duration
}
}
}
})
}