public class ScrollerBottomLayoutDelegation {
private NestedScrollViewmNestedScroller;
private ViewGroup mBottomLayout;
private ScrollerBottomLayoutDelegation(NestedScrollView scroller, ViewGroup view){
this.mNestedScroller = scroller;
this.mBottomLayout = view;
init();
}
/**
* 开始初始化代理
*/
private void init() {
mNestedScroller.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
int dy = scrollY - oldScrollY;
// 第一次调用的时候 dy = nowYOffset
// 随后调用的时候可以做是变化量dy的叠加
// 在移动的过程中mBottomLayout.getTop()始终不会变
int nowYOffset = (int) (dy + mBottomLayout.getTranslationY());
Log.d("@@@", "dy = " + dy + " , nowYOffset = " + nowYOffset + " , top = " + mBottomLayout.getTop());
// scrollTo(),scrollBy():移动view的显示位置,并不移动它的点击位置
// setTranslationX():设置x轴平衡距离,将view的点击位置和显示位置同时移动
// 取消当前正在运行或者挂起的属性动画
ViewCompat.animate(mBottomLayout).cancel();
if (dy > 0) { // 手指向顶部移动 布局隐藏
if (nowYOffset < mBottomLayout.getHeight()) {
mBottomLayout.setTranslationY(nowYOffset);
} else {
mBottomLayout.setTranslationY(mBottomLayout.getHeight());
}
} else if (dy < 0) { // 手指向底部移动
if (nowYOffset < 0) {
mBottomLayout.setTranslationY(0);
} else {
mBottomLayout.setTranslationY(nowYOffset);
}
}
}
});
mNestedScroller.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// positive to check scrolling down 经测试:如果已经滑动到底部时再把手指往上滑回调该方法
if (!mNestedScroller.canScrollVertically(1)) {
animateHide();
return false;
}
// Negative to check scrolling up 经测试:如果已经滑动到顶部时再把手指往下滑回调该方法
if (!mNestedScroller.canScrollVertically(-1)) {
animateShow();
return false;
}
if (mNestedScroller.getScrollY() <= 0) return false;
if (mBottomLayout.getTranslationY() >= mBottomLayout.getHeight() / 2) {
// 手指向顶部滑动
animateHide();
} else {
animateShow();
}
}
return false;
}
});
}
public static void delegation(NestedScrollView scroller, ViewGroup view){
new ScrollerBottomLayoutDelegation(scroller, view);
}
// y = top + translationY;
private void animateShow(){
mBottomLayout.animate()
.translationY(0)
.setInterpolator(new LinearInterpolator())
.setDuration(180);
}
private void animateHide(){
mBottomLayout.animate()
.translationY(mBottomLayout.getHeight())
.setInterpolator(new LinearInterpolator())
.setDuration(180);
}
}