ActionBar隨滑動顯示隱藏
阿新 • • 發佈:2019-02-13
之前寫過一個ActionBar隨著列表或者其他滑動而顯示或者隱藏的文章,前段時間,有了新的想法了,所以,更新一下程式碼,把新的思路放上來。(最新的android design support包當中,已經有類似功能的封裝了,但是貌似不夠靈活,還沒有仔細研究那個包呢)
視訊演示如下:
基本思路:
主要是利用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; } }