1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
public class CodeWebView extends WebView implements NestedScrollingChild, ScrollListener {
public static final String TAG = CodeWebView.class.getSimpleName(); public static final int UP = 1; public static final int DOWN = -1; private final int[] mScrollOffset = new int[2]; private final int[] mScrollConsumed = new int[2]; private final int mTouchSlop; private final int mMinimumVelocity; private final int mMaximumVelocity; private int direction = DOWN; private int mLastMotionY; private int mNestedYOffset; private NestedScrollingChildHelper mChildHelper; private VelocityTracker mVelocityTracker; private boolean allowFly; private int downY; private float mDownY = -1;
public CodeWebView(Context context) { this(context, null); }
public CodeWebView(Context context, AttributeSet attrs) { this(context, attrs, 0); }
public CodeWebView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mChildHelper = new NestedScrollingChildHelper(this); setNestedScrollingEnabled(true); final ViewConfiguration configuration = ViewConfiguration.get(getContext()); mTouchSlop = configuration.getScaledTouchSlop(); mMinimumVelocity = configuration.getScaledMinimumFlingVelocity(); mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
} @Override public boolean onTouchEvent(MotionEvent event) { boolean eventAddedToVelocityTracker = false;
final int action = MotionEventCompat.getActionMasked(event); final int actionIndex = MotionEventCompat.getActionIndex(event);
if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); }
switch (action) { case MotionEvent.ACTION_DOWN: allowFly = false; downY = (int) event.getRawY(); startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL); break; case MotionEvent.ACTION_MOVE: int moveY = (int) event.getRawY(); int dy = -(moveY - downY); downY = moveY; if (dispatchNestedPreScroll(0, dy, mScrollConsumed, mScrollOffset)) { dy -= mScrollConsumed[1]; scrollBy(0, dy); } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: mVelocityTracker.addMovement(event); eventAddedToVelocityTracker = true; mVelocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); int mScrollPointerId = MotionEventCompat.getPointerId(event, actionIndex); float vY = -VelocityTrackerCompat.getYVelocity(mVelocityTracker, mScrollPointerId); if (Math.abs(vY) > mMinimumVelocity && !dispatchNestedPreFling(0, vY)) { dispatchNestedFling(0, vY, true); logi("dispatchNestedFling"); } resetTouch(); break; } if (!eventAddedToVelocityTracker) { mVelocityTracker.addMovement(event); } return true;
}
private void resetTouch() { if (mVelocityTracker != null) { mVelocityTracker.clear(); } stopNestedScroll(); }
@Override public void setNestedScrollingEnabled(boolean enabled) { mChildHelper.setNestedScrollingEnabled(enabled); }
@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); }
public void log(String s) { Log.e(TAG, s); }
public void logi(String s) { Log.i(TAG, s); }
public void logw(String s) { Log.w(TAG, s); } }
|