package com.smartdot.cgt.view; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.GestureDetector.OnGestureListener; import android.view.MotionEvent; import android.view.View; import android.view.animation.Animation; import android.view.animation.LinearInterpolator; import android.view.animation.Transformation; /** * 图片浏览View */ public class FlingView extends View implements OnGestureListener { public abstract class OnIndexChange { public abstract void onIndexChanged(int nowIndex); } private OnIndexChange onIndexChange; private Bitmap bitmap; private Bitmap nBitmap; private Bitmap fBitmap; private int OffsetX = 0; private int OffsetY = 0; private int position = 0; int mLastFlingX = 0; boolean OffsetRight = false; private Bitmap[] bitmaps; public OnIndexChange getOnIndexChange() { return onIndexChange; } public void setOnIndexChange(OnIndexChange onIndexChange) { this.onIndexChange = onIndexChange; } public int getPosition() { return position; } public void setPosition(int position) { if (this.position != position) { this.position = position; bitmap = getBitmap(position); if (position < bitmaps.length - 1) { nBitmap = getBitmap(position + 1); } if (position > 0) { fBitmap = getBitmap(position - 1); } invalidate(); } } public Bitmap[] getBitmaps() { return bitmaps; } public void setBitmaps(Bitmap[] bitmaps) { this.bitmaps = bitmaps; bitmap = getBitmap(position); if (position < bitmaps.length - 1) { nBitmap = getBitmap(position + 1); } if (position > 0) { fBitmap = getBitmap(position - 1); } invalidate(); } public FlingView(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void draw(Canvas canvas) { Paint p = new Paint(); canvas.drawColor(Color.BLACK); if (OffsetX < 0) { if (nBitmap != null) { Rect rectTemp = new Rect(this.getWidth() + 15 + OffsetX, 0, this.getWidth() + 15 + OffsetX + this.getWidth(), nBitmap.getHeight()* this.getWidth()/nBitmap.getWidth()); canvas.drawBitmap(nBitmap, null, rectTemp, p); } } else if (OffsetX > 0) { if (fBitmap != null) { Rect rectTemp = new Rect(-this.getWidth() - 15 + OffsetX, 0, -this.getWidth() - 15 + OffsetX + this.getWidth(), fBitmap.getHeight() * this.getWidth()/fBitmap.getWidth()); canvas.drawBitmap(fBitmap, null, rectTemp, p); } } if (bitmap != null) { Rect rectTemp = new Rect(OffsetX, OffsetY, OffsetX + this.getWidth(), OffsetY + bitmap.getHeight()*this.getWidth()/bitmap.getWidth()); canvas.drawBitmap(bitmap, null, rectTemp, p); } } public void handleScroll(int deltaX) { if (deltaX > 0) { OffsetX -= -deltaX; } else { OffsetX += deltaX; } invalidate(); } // 标记为可以切换到下一张 boolean flag = false; // 标记为需要向右滑动 boolean flag1 = false; // 标记为需要向左滑动 boolean flag2 = false; private GestureDetector myGesture = new GestureDetector(this); class MyAnimation extends Animation { private int temp; @Override public void initialize(int width, int height, int parentWidth, int parentHeight) { temp = OffsetX; super.initialize(width, height, parentWidth, parentHeight); setDuration(500); setFillAfter(true); setInterpolator(new LinearInterpolator()); } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { // Log.i("bb", "OffsetX==>"+OffsetX); // 需要滑动图片时根据方向来变换OffsetX大小 if (flag) { if (temp > 0) { OffsetX = (int) ((FlingView.this.getWidth() + 15 - temp) * interpolatedTime + temp); } else { OffsetX = (int) ((-FlingView.this.getWidth() - 15 - temp) * interpolatedTime + temp); } // 不需要变换的情况 } else { OffsetX = (int) (temp * (1 - interpolatedTime)); } invalidate(); } } // 动画结束后需要做一些工作 @Override protected void onAnimationEnd() { if (flag1) { nBitmap = bitmap; bitmap = fBitmap; fBitmap = null; position = position - 1; } else if (flag2) { fBitmap = bitmap; bitmap = nBitmap; nBitmap = null; position = position + 1; } flag1 = false; flag2 = false; OffsetX = 0; if (fBitmap == null && OffsetX == 0) { if (position > 0) { fBitmap = getBitmap(position - 1); } } else if (nBitmap == null && OffsetX == 0) { if (position < bitmaps.length - 1) { nBitmap = getBitmap(position + 1); } } clearAnimation(); flag = false; if (onIndexChange != null) { onIndexChange.onIndexChanged(position); } } public void startFling(int paramFloat1) { if (OffsetX > this.getWidth() / 3) { if (fBitmap != null) { flag = true; flag1 = true; } } else if (OffsetX < -this.getWidth() / 3) { if (nBitmap != null) { flag = true; flag2 = true; } } // 开始动画效果 startAnimation(new MyAnimation()); invalidate(); } /** * 获得当前位置的图片 * * @param currentPos * @return */ public Bitmap getBitmap(int currentPos) { if (currentPos > bitmaps.length - 1) { return null; } Bitmap currBitmap = bitmaps[currentPos]; OffsetX = 0; OffsetY = 0; return currBitmap; } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_UP: this.startFling(0); break; } myGesture.onTouchEvent(event); return true; } @Override public boolean onDown(MotionEvent e) { return false; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { this.startFling((int) -velocityX); return true; } @Override public void onLongPress(MotionEvent e) { } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { this.handleScroll(-1 * (int) distanceX); return true; } @Override public void onShowPress(MotionEvent e) { } @Override public boolean onSingleTapUp(MotionEvent e) { return false; } }