@Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); if (listener != null) { listener.onScrollChanged(this, l, t, oldl, oldt); } }
@Override public void computeScroll() { if (scroller.computeScrollOffset()) { if (this.onScrollChangedListener != null) { onScrollChangedListener.OnHorizontalScrollChanged( this, SCROLLING, scroller.getCurrX() - offX); onScrollChangedListener.OnVerticalScrollChanged( this, SCROLLING, scroller.getCurrY() - offY); } offX = scroller.getCurrX(); offY = scroller.getCurrY(); invalidate(); } else { if (scrolling) { if (this.onScrollChangedListener != null) { onScrollChangedListener.OnHorizontalScrollChanged(this, SCROLL_END, 0); onScrollChangedListener.OnVerticalScrollChanged(this, SCROLL_END, 0); } scrolling = false; } } }
@Override protected void onScrollChanged(int l, int t, int oldl, int oldt) { super.onScrollChanged(l, t, oldl, oldt); listener.onScrollChanged(l, t, oldl, oldt); }
@Override public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); if (velocityTracker == null) velocityTracker = VelocityTracker.obtain(); velocityTracker.addMovement(event); if (event.getAction() == MotionEvent.ACTION_DOWN) { if (!scroller.isFinished()) scroller.abortAnimation(); lastX = event.getX(); lastY = event.getY(); draggingX = draggingY = false; } else if (event.getAction() == MotionEvent.ACTION_MOVE) { if (draggingX || Math.abs(event.getX() - lastX) > touchSlop) { this.offX += (event.getX() - lastX); if (this.getWidth() > worldWidth) offX = 0; else if (offX > 0) offX = 0; else if (offX < this.getWidth() - worldWidth) offX = this.getWidth() - worldWidth; if (!draggingX) { if (this.onScrollChangedListener != null) onScrollChangedListener.OnHorizontalScrollChanged( this, SCROLL_START, (int) (event.getX() - lastX)); } else { if (this.onScrollChangedListener != null) onScrollChangedListener.OnHorizontalScrollChanged( this, SCROLLING, (int) (event.getX() - lastX)); } lastX = event.getX(); draggingX = true; } if (draggingY || Math.abs(event.getY() - lastY) > touchSlop) { this.offY += (event.getY() - lastY); if (this.getHeight() > worldHeight) offY = 0; else if (offY > 0) offY = 0; else if (offY < this.getHeight() - worldHeight) offY = this.getHeight() - worldHeight; if (!draggingY) { if (this.onScrollChangedListener != null) onScrollChangedListener.OnVerticalScrollChanged( this, SCROLL_START, (int) (event.getY() - lastY)); } else { if (this.onScrollChangedListener != null) onScrollChangedListener.OnVerticalScrollChanged( this, SCROLLING, (int) (event.getY() - lastY)); } lastY = event.getY(); draggingY = true; } if (draggingX || draggingY) this.invalidate(); } else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) { velocityTracker.computeCurrentVelocity(1000, maximumVelocity); float vx = velocityTracker.getXVelocity(); float vy = velocityTracker.getYVelocity(); int minX, minY; boolean flip = false; float minTan = 3.0f; // 当斜率大于minTan时忽略小方向的速度 if (Math.abs(vx) < minimumVelocity || this.getWidth() > worldWidth || Math.abs(vy / vx) > minTan) { vx = 0; if (this.getWidth() > worldWidth) minX = 0; else minX = this.getWidth() - worldWidth; } else { minX = this.getWidth() - worldWidth; flip = true; } if (Math.abs(vy) < minimumVelocity || this.getHeight() > worldHeight || Math.abs(vx / vy) > minTan) { vy = 0; if (this.getHeight() > worldHeight) minY = 0; else minY = this.getHeight() - worldHeight; } else { minY = this.getHeight() - worldHeight; flip = true; } if (flip) { scrolling = true; scroller.fling(offX, offY, (int) vx, (int) vy, minX, 0, minY, 0); this.invalidate(); } else { if (this.onScrollChangedListener != null) { if (draggingX) { onScrollChangedListener.OnHorizontalScrollChanged(this, SCROLL_END, 0); } if (draggingY) { onScrollChangedListener.OnVerticalScrollChanged(this, SCROLL_END, 0); } } } draggingX = draggingY = false; velocityTracker.recycle(); velocityTracker = null; this.invalidate(); } return true; }