參考博客,http://blog.csdn.net/lmj623565791/article/details/49300989
public class LargeImageView extends View implements View.OnTouchListener,GestureDetector.OnGestureListener {
private BitmapRegionDecoder mDecoder;
/**
* 圖片的寬度和高度
*/
private int mImageWidth, mImageHeight;
/**
* 繪製的區域
*/
private volatile Rect mRect = new Rect();
private GestureDetector mRealDetector;
private ValueAnimator mValueAnimator;
private static final BitmapFactory.Options options = new BitmapFactory.Options();
static {
options.inPreferredConfig = Bitmap.Config.RGB_565;
}
private int lastY;
public void setInputStream(InputStream is) {
try {
mDecoder = BitmapRegionDecoder.newInstance(is, false);
BitmapFactory.Options tmpOptions = new BitmapFactory.Options();
// Grab the bounds for the scene dimensions
tmpOptions.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, tmpOptions);
mImageWidth = /*tmpOptions.outWidth*/mDecoder.getWidth();
mImageHeight = /*tmpOptions.outHeight*/mDecoder.getHeight();
requestLayout();
invalidate();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null)
is.close();
} catch (Exception e) {
}
}
}
public void init() {
mValueAnimator = new ValueAnimator();
mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int animatedValue = (int) valueAnimator.getAnimatedValue();
if (animatedValue > mImageHeight)
valueAnimator.cancel();
int dy = animatedValue - lastY;
mRect.offset(0,dy);
checkHeight();
invalidate();
lastY = animatedValue;
}
});
mRealDetector = new GestureDetector(this);
setOnTouchListener(this);
}
private void checkWidth() {
Rect rect = mRect;
int imageWidth = mImageWidth;
int imageHeight = mImageHeight;
if (rect.right > imageWidth) {
rect.right = imageWidth;
rect.left = imageWidth - getWidth();
}
if (rect.left < 0) {
rect.left = 0;
rect.right = getWidth();
}
}
private void checkHeight() {
Rect rect = mRect;
int imageWidth = mImageWidth;
int imageHeight = mImageHeight;
if (rect.bottom > imageHeight) {
rect.bottom = imageHeight;
rect.top = imageHeight - getHeight();
}
if (rect.top < 0) {
rect.top = 0;
rect.bottom = getHeight();
}
}
public LargeImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
@Override
protected void onDraw(Canvas canvas) {
Bitmap bm = mDecoder.decodeRegion(mRect, options);
canvas.drawBitmap(bm, 0, 0, null);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
int height = getMeasuredHeight();
int imageWidth = mImageWidth;
int imageHeight = mImageHeight;
//默認直接顯示圖片的中心區域,可以自己去調節
mRect.left = imageWidth / 2 - width / 2;
// mRect.top = imageHeight / 2 - height / 2;
mRect.top = 0;
mRect.right = mRect.left + width;
// mRect.bottom = mRect.top + height;
mRect.bottom = height;
}
@Override
public boolean onDown(MotionEvent motionEvent) {
if (null != mValueAnimator)
mValueAnimator.cancel();
return false;
}
@Override
public void onShowPress(MotionEvent motionEvent) {
}
@Override
public boolean onSingleTapUp(MotionEvent motionEvent) {
return false;
}
@Override
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float distanceX, float distanceY) {
int moveX = (int) (distanceX+0.5f);
int moveY = (int) (distanceY+0.5f);
if (mImageWidth > getWidth()) {
mRect.offset(moveX, 0);
checkWidth();
invalidate();
}
if (mImageHeight > getHeight()) {
mRect.offset(0, moveY);
checkHeight();
invalidate();
}
return false;
}
@Override
public void onLongPress(MotionEvent motionEvent) {
}
@Override
public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float speedX, float speedY) {
if (mImageHeight > getHeight()) {
//加速度 a = -4000/s ,time = speedY/ a , flingDy = (speedY + 0) /2 * t,speedY最大值是-8000 ~ 8000
float a = 2700;
int time = (int) Math.abs(speedY/a*1000);//乘以1000變成毫秒
int flingDy = -(int) (speedY/2*time/1000);//speed是以秒爲單位的所以要除1000
lastY = (int) motionEvent1.getY();
mValueAnimator.setIntValues((int) motionEvent1.getY(), (int) motionEvent1.getY()+flingDy);
mValueAnimator.setInterpolator(new DecelerateInterpolator(20f));
mValueAnimator.setDuration(time*10);
mValueAnimator.start();
}
return false;
}
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return mRealDetector.onTouchEvent(motionEvent);
}
}
使用:
<xxx.xxx.xxx.LargeImageView
android:id="@+id/largeImage"
android:focusable="true"
android:clickable="true"
android:background="@color/blue_33a6ec"
android:layout_marginRight="20dp"
android:layout_marginTop="20dp"
android:layout_marginLeft="20dp"
android:layout_width="match_parent"
android:layout_height="match_parent" />
try {
largeImage.setInputStream(new FileInputStream(filePath));
} catch (FileNotFoundException e) {
e.printStackTrace();
}