最近整理了一下項目中用到的圖片瀏覽的一些代碼,這個圖片瀏覽工具與系統的相冊功能類似,全屏瀏覽圖片,支持一系列手勢操作,滑動切換以及多指縮放。
圖片列表的容器使用了系統的gallery類實現,在View的實現上,重寫了系統的ImageView對象,監聽手勢操作。
兩個主要類的實現代碼如下:
gallery的實現:
View Code
package com.xiaobai.viewimage; import android.content.Context; import android.graphics.Matrix; import android.graphics.Rect; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.widget.Gallery; public class PicGallery extends Gallery { private static final boolean DEBUG = Logger.DEBUG && false; private GestureDetector gestureScanner; private MyImageView imageView; public PicGallery(Context context) { super(context); } public PicGallery(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public void setDetector(GestureDetector dectector) { gestureScanner = dectector; } public PicGallery(Context context, AttributeSet attrs) { super(context, attrs); this.setOnTouchListener(new OnTouchListener() { float baseValue; float originalScale; @Override public boolean onTouch(View v, MotionEvent event) { View view = PicGallery.this.getSelectedView(); if (view instanceof MyImageView) { imageView = (MyImageView) view; if (event.getAction() == MotionEvent.ACTION_DOWN) { baseValue = 0; originalScale = imageView.getScale(); } if (event.getAction() == MotionEvent.ACTION_MOVE) { if (event.getPointerCount() == 2) { float x = event.getX(0) - event.getX(1); float y = event.getY(0) - event.getY(1); float value = (float) Math.sqrt(x * x + y * y);// 計算兩點的距離 // System.out.println("value:" + value); if (baseValue == 0) { baseValue = value; } else { float scale = value / baseValue;// 當前兩點間的距離除以手指落下時兩點間的距離就是需要縮放的比例。 // scale the image imageView.zoomTo(originalScale * scale, x + event.getX(1), y + event.getY(1)); } } } } return false; } }); } float v[] = new float[9]; @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { View view = PicGallery.this.getSelectedView(); if (view instanceof MyImageView) { float xdistance = calXdistance(e1, e2); float min_distance = PictureViewActivity.screenWidth / 4f; Logger.d(DEBUG,"xdistance=" + xdistance + ",min_distance=" + min_distance); if (isScrollingLeft(e1, e2) && xdistance > min_distance) { kEvent = KeyEvent.KEYCODE_DPAD_LEFT; } else if (!isScrollingLeft(e1, e2) && xdistance > min_distance) { kEvent = KeyEvent.KEYCODE_DPAD_RIGHT; } imageView = (MyImageView) view; Matrix m = imageView.getImageMatrix(); m.getValues(v); // 圖片實時的上下左右坐標 float left, right; // 圖片的實時寬,高 float width = imageView.getScale() * imageView.getImageWidth(); float height = imageView.getScale() * imageView.getImageHeight(); if ((int) width <= PictureViewActivity.screenWidth && (int) height <= PictureViewActivity.screenHeight)// 如果圖片當前大小<屏幕大小,直接處理滑屏事件 { super.onScroll(e1, e2, distanceX, distanceY); } else { left = v[Matrix.MTRANS_X]; right = left + width; Rect r = new Rect(); imageView.getGlobalVisibleRect(r); if (distanceX > 0)// 向左滑動 { if (r.left > 0 || right < PictureViewActivity.screenWidth) {// 判斷當前ImageView是否顯示完全 super.onScroll(e1, e2, distanceX, distanceY); } else { imageView.postTranslate(-distanceX, -distanceY); } } else if (distanceX < 0)// 向右滑動 { if (r.right < PictureViewActivity.screenWidth || left > 0) { super.onScroll(e1, e2, distanceX, distanceY); } else { imageView.postTranslate(-distanceX, -distanceY); } } } } else { super.onScroll(e1, e2, distanceX, distanceY); } return false; } private boolean isScrollingLeft(MotionEvent e1, MotionEvent e2) { return e2.getX() > e1.getX(); } private float calXdistance(MotionEvent e1, MotionEvent e2) { return Math.abs(e2.getX() - e1.getX()); } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { return false; } @Override public boolean onTouchEvent(MotionEvent event) { //Logger.d(DEBUG,"[PicGallery.onTouchEvent]"+"PicGallery.onTouchEvent"); if (gestureScanner != null) { gestureScanner.onTouchEvent(event); } switch (event.getAction()) { case MotionEvent.ACTION_UP: // 判斷邊界是否越界 View view = PicGallery.this.getSelectedView(); if (view instanceof MyImageView) { if(kEvent != KEY_INVALID) { // 是否切換上一頁或下一頁 onKeyDown(kEvent, null); kEvent = KEY_INVALID; } imageView = (MyImageView) view; float width = imageView.getScale() * imageView.getImageWidth(); float height = imageView.getScale() * imageView.getImageHeight(); // Logger.LOG("onTouchEvent", "width=" + width + ",height=" // + height + ",screenWidth=" // + PictureViewActivity.screenWidth + ",screenHeight=" // + PictureViewActivity.screenHeight); if ((int) width <= PictureViewActivity.screenWidth && (int) height <= PictureViewActivity.screenHeight)// 如果圖片當前大小<屏幕大小,判斷邊界 { break; } float v[] = new float[9]; Matrix m = imageView.getImageMatrix(); m.getValues(v); float top = v[Matrix.MTRANS_Y]; float bottom = top + height; if (top < 0 && bottom < PictureViewActivity.screenHeight) { // imageView.postTranslateDur(-top, 200f); imageView.postTranslateDur(PictureViewActivity.screenHeight - bottom, 200f); } if (top > 0 && bottom > PictureViewActivity.screenHeight) { // imageView.postTranslateDur(PictureViewActivity.screenHeight // - bottom, 200f); imageView.postTranslateDur(-top, 200f); } float left =v[Matrix.MTRANS_X]; float right = left + width; if(left<0 && right< PictureViewActivity.screenWidth){ // imageView.postTranslateXDur(-left, 200f); imageView.postTranslateXDur(PictureViewActivity.screenWidth - right, 200f); } if(left>0 && right>PictureViewActivity.screenWidth){ // imageView.postTranslateXDur(PictureViewActivity.screenWidth // - right, 200f); imageView.postTranslateXDur(-left, 200f); } } break; } return super.onTouchEvent(event); } int kEvent = KEY_INVALID; //invalid public static final int KEY_INVALID = -1; }
重寫ImageView:
View Code
apk下載鏈接:http://download.csdn.net/download/aimfaraway/5349925
源碼鏈接:https://github.com/devxiaobai/ViewImage
