ActionBar随滑动显示隐藏

之前写过一个ActionBar随着列表或者其他滑动而显示或者隐藏的文章,前段时间,有了新的想法了,所以,更新一下代码,把新的思路放上来。(最新的android design support包当中,已经有类似功能的封装了,但是貌似不够灵活,还没有仔细研究那个包呢)

原文地址:http://blog.csdn.net/boybeak/article/details/41410113

新视线思路的Github地址:https://github.com/boybeak/ScrollTrack

如果你会科学上网法,可以去PlayStore安装应用:https://play.google.com/store/apps/details?id=com.beak.scrolltrack

视频演示如下:

http://v.youku.com/v_show/id_XMTM1NzQ3ODA5Mg==.html?from=y1.7-1.2#paction

基本思路:

主要是利用RecyclerView 的OnScrollListener的两个回调函数OnScrollStateChange和OnScrolled,去控制指定view的显示,位置和隐藏,再利用动画,使动作更为流畅。

在代码中,有两个类:TopTrackListener和BottomTrackListener,分别用来控制向上隐藏和向下隐藏。这样的思路,可以移植到其他的可以随手滑动的控件上。

废话不多说,以TopTrackListener为例,代码如下:

public class TopTrackListener extends RecyclerView.OnScrollListener {

    private static final String TAG = TopTrackListener.class.getSimpleName();

    private int mLastDy = 0;
    private int mTotalDy = 0;

    private View mTargetView = null;

    private ObjectAnimator mAnimator = null;

    private boolean isAlreadyHide = false, isAlreadyShow = false;

    public TopTrackListener(View target) {
        if (target == null) {
            throw new IllegalArgumentException("target shouldn't be null");
        }
        mTargetView = target;
    }

    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        switch (newState) {
            case RecyclerView.SCROLL_STATE_IDLE:
                final float transY = mTargetView.getTranslationY();
                int distance = -mTargetView.getBottom();

                if (transY == 0 || transY == distance) {
                    return;
                }
                if (mLastDy > 0) {
                    mAnimator = animateHide(mTargetView);
                } else {
                    mAnimator = animateShow(mTargetView);
                }
                break;
            case RecyclerView.SCROLL_STATE_DRAGGING:
                if (mAnimator != null && mAnimator.isRunning()) {
                    mAnimator.cancel();
                }
                break;
            case RecyclerView.SCROLL_STATE_SETTLING:
                break;
        }
    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        mTotalDy -= dy;
        mLastDy = dy;
        final float transY = mTargetView.getTranslationY();
        float newTransY;
        int distance = -mTargetView.getBottom();

        if (mTotalDy >= distance && dy > 0) {
            return;
        }

        if (isAlreadyHide && dy > 0) {
            return;
        }

        if (isAlreadyShow && dy < 0) {
            return;
        }

        newTransY = transY - dy;
        if (newTransY < distance) {
            newTransY = distance;
        } else if (newTransY == distance) {
            return;
        } else if (newTransY > 0) {
            newTransY = 0;
        } else if (newTransY == 0) {
            return;
        }

        mTargetView.setTranslationY(newTransY);
        isAlreadyHide = newTransY == distance;
        isAlreadyShow = newTransY == 0;

    }

    private ObjectAnimator animateHide (View targetView) {
        int distance = -targetView.getBottom();
        return animationFromTo(targetView, targetView.getTranslationY(), distance);
    }

    private ObjectAnimator animateShow (View targetView) {
        return animationFromTo(targetView, targetView.getTranslationY(), 0);
    }

    private ObjectAnimator animationFromTo (View view, float start, float end) {
        String propertyName = "translationY";
        ObjectAnimator animator = ObjectAnimator.ofFloat(view, propertyName, start, end);
        animator.start();
        return animator;
    }

}


猜你喜欢

转载自blog.csdn.net/boybeak/article/details/49052813
今日推荐