package com.mjj.nestedscroll.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.util.AttributeSet; import android.view.MotionEvent; import android.widget.ImageView; public class MyImageView extends ImageView implements NestedScrollingChild{ public MyImageView(Context context) { super(context); init(); } public MyImageView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public MyImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } NestedScrollingChildHelper nestedScrollingChildHelper; void init() { nestedScrollingChildHelper = new NestedScrollingChildHelper(this); nestedScrollingChildHelper.setNestedScrollingEnabled(true); } private int mScrollPointerId = -1; private int mLastTouchY; private final int[] mScrollOffset = new int[2]; private final int[] mScrollConsumed = new int[2]; private final int[] mNestedOffsets = new int[2]; @Override public boolean onTouchEvent(MotionEvent e) { final boolean canScrollVertically = true; final MotionEvent vtev = MotionEvent.obtain(e); final int action = MotionEventCompat.getActionMasked(e); if (action == MotionEvent.ACTION_DOWN) { mNestedOffsets[0] = mNestedOffsets[1] = 0; } vtev.offsetLocation(mNestedOffsets[0], mNestedOffsets[1]); switch (action) { case MotionEvent.ACTION_DOWN: { mScrollPointerId = MotionEventCompat.getPointerId(e, 0); mLastTouchY = (int) (e.getY() + 0.5f); int nestedScrollAxis = ViewCompat.SCROLL_AXIS_NONE; if (canScrollVertically) { nestedScrollAxis |= ViewCompat.SCROLL_AXIS_VERTICAL; } startNestedScroll(nestedScrollAxis); } break; case MotionEvent.ACTION_MOVE: { final int index = MotionEventCompat.findPointerIndex(e, mScrollPointerId); if (index < 0) { return false; } final int y = (int) (MotionEventCompat.getY(e, index) + 0.5f); int dx = 0; int dy = mLastTouchY - y; dispatchNestedPreScroll(dx, dy, mScrollConsumed, mScrollOffset); } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: stopNestedScroll(); break; } vtev.recycle(); return true; } @Override public void setNestedScrollingEnabled(boolean enabled) { nestedScrollingChildHelper.setNestedScrollingEnabled(enabled); } @Override public boolean isNestedScrollingEnabled() { return nestedScrollingChildHelper.isNestedScrollingEnabled(); } @Override public boolean startNestedScroll(int axes) { return nestedScrollingChildHelper.startNestedScroll(axes); } @Override public void stopNestedScroll() { nestedScrollingChildHelper.stopNestedScroll(); } @Override public boolean hasNestedScrollingParent() { return nestedScrollingChildHelper.hasNestedScrollingParent(); } @Override public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) { return nestedScrollingChildHelper.dispatchNestedScroll(dxConsumed,dyConsumed,dxUnconsumed,dyUnconsumed,offsetInWindow); } @Override public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) { return nestedScrollingChildHelper.dispatchNestedPreScroll(dx,dy,consumed,offsetInWindow); } @Override public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) { return nestedScrollingChildHelper.dispatchNestedFling(velocityX,velocityY,consumed); } @Override public boolean dispatchNestedPreFling(float velocityX, float velocityY) { return nestedScrollingChildHelper.dispatchNestedPreFling(velocityX,velocityY); } }