Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
package com.segmentfault.app.view;
import android.content.Context;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.NestedScrollingChild;
import android.support.v4.view.NestedScrollingChildHelper;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
/**
* Created by geminiwen on 15/6/2.
*/
public class NestedScrollSwipeRefreshLayout extends SwipeRefreshLayout implements NestedScrollingChild{
private static final int INVALID_POINTER = -1;
private int mTouchSlop;
private int mActivePointerId = INVALID_POINTER;
private NestedScrollingChildHelper mChildHelper;
public NestedScrollSwipeRefreshLayout(Context context) {
this(context, null);
}
public NestedScrollSwipeRefreshLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mChildHelper = new NestedScrollingChildHelper(this);
setNestedScrollingEnabled(true);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
@Override
public void setNestedScrollingEnabled(boolean enabled) {
mChildHelper.setNestedScrollingEnabled(enabled);
}
@Override
public boolean isNestedScrollingEnabled() {
return mChildHelper.isNestedScrollingEnabled();
}
@Override
public boolean startNestedScroll(int axes) {
return mChildHelper.startNestedScroll(axes);
}
@Override
public void stopNestedScroll() {
mChildHelper.stopNestedScroll();
}
@Override
public boolean hasNestedScrollingParent() {
return mChildHelper.hasNestedScrollingParent();
}
@Override
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) {
return mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
}
@Override
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
}
@Override
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
return mChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
}
@Override
public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
return mChildHelper.dispatchNestedPreFling(velocityX, velocityY);
}
private float mLastMotionY;
private final int[] mScrollOffset = new int[2];
private final int[] mScrollConsumed = new int[2];
private boolean mIsBeginDrag = false;
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = MotionEventCompat.getActionMasked(ev);
switch (action) {
case MotionEvent.ACTION_DOWN: {
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
final float initialDownY = getMotionEventY(ev, mActivePointerId);
if (initialDownY == -1) {
return false;
}
mLastMotionY = initialDownY;
startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
super.onInterceptTouchEvent(ev);
mIsBeginDrag = false;
break;
}
case MotionEvent.ACTION_MOVE: {
if (mActivePointerId == INVALID_POINTER) {
return false;
}
final float y = getMotionEventY(ev, mActivePointerId);
if (y == -1) {
return false;
}
int deltaY = (int)(mLastMotionY - y);
mLastMotionY = y;
if (Math.abs(deltaY) >= mTouchSlop) {
mIsBeginDrag = true;
}
if (mIsBeginDrag && dispatchNestedPreScroll(0, deltaY, mScrollConsumed, mScrollOffset)) {
mLastMotionY -= mScrollOffset[1];
deltaY -= mScrollConsumed[1];
ev.offsetLocation(0, mScrollConsumed[1]);
if (dispatchNestedScroll(0, 0, 0, deltaY, mScrollOffset)) {
mLastMotionY -= mScrollOffset[1];
ev.offsetLocation(0, mScrollOffset[1]);
}
return false;
} else {
return super.onInterceptTouchEvent(ev);
}
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP: {
stopNestedScroll();
mActivePointerId = INVALID_POINTER;
mIsBeginDrag = false;
return super.onInterceptTouchEvent(ev);
}
}
return super.onInterceptTouchEvent(ev);
}
private float getMotionEventY(MotionEvent ev, int activePointerId) {
final int index = MotionEventCompat.findPointerIndex(ev, activePointerId);
if (index < 0) {
return -1;
}
return MotionEventCompat.getY(ev, index);
}
}
@XuZheBao

This comment has been minimized.

Copy link

commented Feb 19, 2017

SwipeRefreshLayout本身就已经实现了NestedScrollingChild接口的

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.