Android开发艺术探索
package com.example.apple.quickdemo.realview;
import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.widget.LinearLayout;
import android.widget.Scroller;
import static android.content.ContentValues.TAG;
/**
* Created by apple on 2017/7/7.
* 外部拦截标准模板
*/
public class RealPullRefreshView extends LinearLayout {
private int mTouchSlop;
// 分别记录上次滑动的坐标
private int mLastX = 0;
private int mLastY = 0;
// 分别记录上次滑动的坐标(onInterceptTouchEnvent)
private int mLastXIntercept = 0;
private int mLastYIntercept = 0;
private Scroller mScroller;
private VelocityTracker mVelocityTracker;
private RecyclerView mRv;
public RealPullRefreshView(Context context) {
super(context);
init();
}
public RealPullRefreshView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
mScroller = new Scroller(getContext());
mVelocityTracker = VelocityTracker.obtain();
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
mRv = (RecyclerView) getChildAt(1);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
boolean intercepted = false;
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
intercepted = false;
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
intercepted = true;
}
break;
}
case MotionEvent.ACTION_MOVE: {
int deltaX = x - mLastXIntercept;
int deltaY = y - mLastYIntercept;
// ******************这里说明什么规则下,拦截,其余代码不要动了,其余代码指的是处理滑动冲突的代码***************
int firstCompletelyVisibleItemPosition = ((LinearLayoutManager) mRv.getLayoutManager()).findFirstCompletelyVisibleItemPosition();
if (firstCompletelyVisibleItemPosition == 0 && deltaY > 0) {//拉倒最顶部,继续往下拉,将拉出头布局,要父布局拦截
intercepted = true;
} else if (getScrollY() < 0) {//表示头布局已经向下拉出来,头布局已经显示了,要父布局拦截
intercepted = true;
} else {
intercepted = false;//不要父布局拦截了
}
// ******************什么规则下,拦截***************
break;
}
case MotionEvent.ACTION_UP: {
intercepted = false;
break;
}
default:
break;
}
Log.d(TAG, "intercepted=" + intercepted);
mLastX = x;
mLastY = y;
mLastXIntercept = x;
mLastYIntercept = y;
return intercepted;
}
/**
* 下面不同布局,不同的滑动需求
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
mVelocityTracker.addMovement(event);
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
}
break;
}
case MotionEvent.ACTION_MOVE: {
Log.e("111", getScrollY() + "");
int deltaX = x - mLastX;
int deltaY = y - mLastY;
if (getScrollY() > 0) {
scrollTo(0, 0);//抖动
} else {
scrollBy(0, -deltaY);
}
break;
}
case MotionEvent.ACTION_UP: {
int scrollY = getScrollY();
if (scrollY > -105) {//头布局显示了不到一半,完全隐藏头布局
smoothScrollBy(0, -scrollY);
} else if (scrollY < -105) {//头布局显示了超过到一半,完全显示头布局
smoothScrollBy(0, -210 - scrollY);
}
mVelocityTracker.clear();
break;
}
default:
break;
}
mLastX = x;
mLastY = y;
return true;
}
private void smoothScrollBy(int dx, int dy) {
mScroller.startScroll(0, getScrollY(), 0, dy, 500);
invalidate();
}
@Override
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}
}
@Override
protected void onDetachedFromWindow() {
mVelocityTracker.recycle();
super.onDetachedFromWindow();
}
}