Android 列表滑动时Toolbar渐变隐藏

  • GradientToolbarOnScrollingListener.java
package com.vincent.listener;

import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;

import com.vincent.util.DensityUtils;

public class GradientToolbarOnScrollingListener extends RecyclerView.OnScrollListener {

    private Toolbar mToolbar;

    private int mDistanceY;
    private int mScrollDistance;

    public GradientToolbarOnScrollingListener(Toolbar toolbar) {
        this(toolbar, 0);
    }

    public GradientToolbarOnScrollingListener(Toolbar toolbar, float dpValue) {
        this(toolbar, DensityUtils.dip2px(toolbar.getContext(), dpValue));
    }

    public GradientToolbarOnScrollingListener(Toolbar toolbar, int scrollY) {
        this.mToolbar = toolbar;
        this.mToolbar.getBackground().setAlpha(0);
        this.mScrollDistance = scrollY;
    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        int verticalOffset = recyclerView.computeVerticalScrollOffset();
        mToolbar.getBackground().setAlpha(getAlpha(verticalOffset));
    }

    private static int minDist = 50;

    private int getAlpha(int scrollY) {
        int scrollDistance = (mScrollDistance > 0) ? mScrollDistance : mToolbar.getBottom();

        if (scrollY > scrollDistance) {
            return 255;
        } else if (scrollY < 50) {
            return 0;
        } else {
            float precent = (float) (scrollY - minDist) / scrollDistance;
            return Math.round(precent * 255);
        }
    }
}
  • ShowHideToolbarOnScrollingListener.java
package com.vincent.listener;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.TargetApi;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.animation.LinearInterpolator;

public final class ShowHideToolbarOnScrollingListener extends RecyclerView.OnScrollListener {

    public static final String SHOW_HIDE_TOOLBAR_LISTENER_STATE = "show-hide-toolbar-listener-state";

    // The elevation of the toolbar when content is scrolled behind
    private static final float TOOLBAR_ELEVATION = 14f;

    private Toolbar toolbar;
    private State state;

    public ShowHideToolbarOnScrollingListener(Toolbar toolbar) {
        this.toolbar = toolbar;
        this.state = new State();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void toolbarSetElevation(float elevation) {
        if (isLollipop()) {
            toolbar.setElevation(elevation == 0 ? 0 : TOOLBAR_ELEVATION);
        }
    }

    private boolean isLollipop() {
        return android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
    }

    private void toolbarAnimateShow(final int verticalOffset) {
        toolbar.animate()
                .translationY(0)
                .setInterpolator(new LinearInterpolator())
                .setDuration(180)
                .setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationStart(Animator animation) {
                        toolbarSetElevation(verticalOffset == 0 ? 0 : TOOLBAR_ELEVATION);
                    }
                });
    }

    private void toolbarAnimateHide() {
        toolbar.animate()
                .translationY(-toolbar.getHeight())
                .setInterpolator(new LinearInterpolator())
                .setDuration(180)
                .setListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        toolbarSetElevation(0);
                    }
                });
    }

    @Override
    public final void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        if (newState == RecyclerView.SCROLL_STATE_IDLE) {
            if (state.scrollingOffset > 0) {
                if (state.verticalOffset > toolbar.getHeight()) {
                    toolbarAnimateHide();
                } else {
                    toolbarAnimateShow(state.verticalOffset);
                }
            } else if (state.scrollingOffset < 0) {
                if (toolbar.getTranslationY() < toolbar.getHeight() * -0.6 && state.verticalOffset > toolbar.getHeight()) {
                    toolbarAnimateHide();
                } else {
                    toolbarAnimateShow(state.verticalOffset);
                }
            }
        }
    }

    @Override
    public final void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        state.verticalOffset = recyclerView.computeVerticalScrollOffset();
        state.scrollingOffset = dy;
        int toolbarYOffset = (int) (dy - toolbar.getTranslationY());
        toolbar.animate().cancel();
        if (state.scrollingOffset > 0) {
            if (toolbarYOffset < toolbar.getHeight()) {
                if (state.verticalOffset > toolbar.getHeight()) {
                    toolbarSetElevation(TOOLBAR_ELEVATION);
                }
                toolbar.setTranslationY(state.translationY = -toolbarYOffset);
            } else {
                toolbarSetElevation(0);
                toolbar.setTranslationY(state.translationY = -toolbar.getHeight());
            }
        } else if (state.scrollingOffset < 0) {
            if (toolbarYOffset < 0) {
                if (state.verticalOffset <= 0) {
                    toolbarSetElevation(0);
                }
                toolbar.setTranslationY(state.translationY = 0);
            } else {
                if (state.verticalOffset > toolbar.getHeight()) {
                    toolbarSetElevation(TOOLBAR_ELEVATION);
                }
                toolbar.setTranslationY(state.translationY = -toolbarYOffset);
            }
        }
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public void onRestoreInstanceState(State state) {
        this.state.verticalOffset = state.verticalOffset;
        this.state.scrollingOffset = state.scrollingOffset;
        if (isLollipop()) {
            toolbar.setElevation(state.elevation);
            toolbar.setTranslationY(state.translationY);
        }
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public State onSaveInstanceState() {
        state.translationY = toolbar.getTranslationY();
        if (isLollipop()) {
            state.elevation = toolbar.getElevation();
        }
        return state;
    }

    /**
     * Parcelable RecyclerView/Toolbar state for simpler saving/restoring its current state.
     */
    public static final class State implements Parcelable {
        public static Creator<State> CREATOR = new Creator<State>() {
            public State createFromParcel(Parcel parcel) {
                return new State(parcel);
            }

            public State[] newArray(int size) {
                return new State[size];
            }
        };

        // Keeps track of the overall vertical offset in the list
        private int verticalOffset;
        // Determines the scroll UP/DOWN offset
        private int scrollingOffset;
        // Toolbar values
        private float translationY;
        private float elevation;

        State() {
        }

        State(Parcel parcel) {
            this.verticalOffset = parcel.readInt();
            this.scrollingOffset = parcel.readInt();
            this.translationY = parcel.readFloat();
            this.elevation = parcel.readFloat();
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel parcel, int flags) {
            parcel.writeInt(verticalOffset);
            parcel.writeInt(scrollingOffset);
            parcel.writeFloat(translationY);
            parcel.writeFloat(elevation);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!针对您的问题,您可以使用 Android 中的 Toolbar 控件来实现滑动渐变标题栏。 具体实现步骤如下: 1. 在布局文件中添加 Toolbar 控件,并设置其高度为 wrap_content。 2. 在代码中通过 findViewById 获取 Toolbar 对象,并调用 setSupportActionBar 方法将其设置为当前 Activity 的 ActionBar。 3. 在 Activity 的 onCreate 方法中,通过 getSupportActionBar().setDisplayHomeAsUpEnabled(true) 设置标题栏左侧显示返回按钮。 4. 在滑动,通过监听 RecyclerView 的滚动事件,动态改变标题栏的背景颜色和透明度,实现滑动渐变效果。 5. 在 onScrollStateChanged 方法中,根据当前滚动状态判断是否需要执行动画效果。 下面是一个简单的示例代码: ```java // 获取 Toolbar 对象 Toolbar toolbar = findViewById(R.id.toolbar); // 将 Toolbar 设置为当前 Activity 的 ActionBar setSupportActionBar(toolbar); // 显示返回按钮 getSupportActionBar().setDisplayHomeAsUpEnabled(true); // 监听 RecyclerView 的滚动事件 recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (newState == RecyclerView.SCROLL_STATE_IDLE) { // 滑动停止执行动画效果 animateToolbarColor(0xFF0000FF, 0x00000000); } } @Override public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); // 获取当前 RecyclerView 的滚动位置 int scrollY = recyclerView.computeVerticalScrollOffset(); // 计算标题栏透明度 int alpha = Math.min(255, scrollY * 2); // 执行动画效果 animateToolbarColor(Color.argb(alpha, 0xFF, 0x00, 0x00), Color.argb(0, 0x00, 0x00, 0x00)); } }); // 改变标题栏背景颜色和透明度的动画效果 private void animateToolbarColor(int fromColor, int toColor) { ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), fromColor, toColor); colorAnimation.setDuration(250); colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animator) { toolbar.setBackgroundColor((int) animator.getAnimatedValue()); } }); colorAnimation.start(); } ``` 希望这个示例能够对您有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值