android学习笔记37--------------多点触控缩放图片及单点触控图片移动

来源:互联网 发布:小米note网络制式指令 编辑:程序博客网 时间:2024/05/16 09:01

转载请注明原文出处:奔跑的蜗牛(袁方的技术博客)点击打开链接

原始图片:


点击放大按钮,或两手拖拉屏幕。


上代码:

public class main extends Activity{/** Called when the activity is first created. */private ImageZoomView mZoomView;private ZoomState mZoomState;private Bitmap mBitmap;private SimpleZoomListener mZoomListener;private ProgressBar progressBar;private Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg){progressBar.setVisibility(View.GONE);mZoomView.setImage(mBitmap);mZoomState = new ZoomState();mZoomView.setZoomState(mZoomState);mZoomListener = new SimpleZoomListener();mZoomListener.setZoomState(mZoomState);mZoomView.setOnTouchListener(mZoomListener);resetZoomState();}};@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);// 隐藏顶部程序名称 写在setContentView(R.layout.xxxx);之前,不然报错requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);requestWindowFeature(Window.FEATURE_NO_TITLE);// 隐藏状态栏getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);setContentView(R.layout.activity_image);mZoomView = (ImageZoomView) findViewById(R.id.zoomView);progressBar = (ProgressBar) findViewById(R.id.progress_large);progressBar.setVisibility(View.VISIBLE);Thread thread = new Thread(new Runnable(){@Overridepublic void run(){/* * 加载网络图片 load form url */// mBitmap =// ImageDownloader.getInstance().getBitmap(url);mBitmap = BitmapFactory.decodeResource(main.this.getResources(), R.drawable.test);handler.sendEmptyMessage(0);}});thread.start();ZoomControls zoomCtrl = (ZoomControls) findViewById(R.id.zoomCtrl);zoomCtrl.setOnZoomInClickListener(new OnClickListener(){@Overridepublic void onClick(View v){float z = mZoomState.getZoom() + 0.25f;mZoomState.setZoom(z);mZoomState.notifyObservers();}});zoomCtrl.setOnZoomOutClickListener(new OnClickListener(){@Overridepublic void onClick(View v){float z = mZoomState.getZoom() - 0.25f;mZoomState.setZoom(z);mZoomState.notifyObservers();}});}@Overrideprotected void onDestroy(){super.onDestroy();if (mBitmap != null)mBitmap.recycle();}private void resetZoomState(){mZoomState.setPanX(0.5f);mZoomState.setPanY(0.5f);mZoomState.setZoom(1f);mZoomState.notifyObservers();}}

public class ImageZoomView extends View implements Observer{private final Paint mPaint =  new Paint(Paint.FILTER_BITMAP_FLAG);private final Rect mRectSrc = new Rect();private final Rect mRectDst = new Rect();private float mAspectQuotient;private Bitmap mBitmap;private ZoomState mState;public ImageZoomView(Context context, AttributeSet attrs){super(context, attrs);}public void setZoomState(ZoomState state){if (mState != null){mState.deleteObserver(this);}mState = state;mState.addObserver(this);invalidate();}protected void onDraw(Canvas canvas){if (mBitmap != null && mState != null){final int viewWidth = getWidth();final int viewHeight = getHeight();final int bitmapWidth = mBitmap.getWidth();final int bitmapHeight = mBitmap.getHeight();final float panX = mState.getPanX();final float panY = mState.getPanY();final float zoomX = mState.getZoomX(mAspectQuotient) * viewWidth/ bitmapWidth;final float zoomY = mState.getZoomY(mAspectQuotient) * viewHeight/ bitmapHeight;// Setup source and destination rectanglesmRectSrc.left = (int) (panX * bitmapWidth - viewWidth / (zoomX * 2));mRectSrc.top = (int) (panY * bitmapHeight - viewHeight/ (zoomY * 2));mRectSrc.right = (int) (mRectSrc.left + viewWidth / zoomX);mRectSrc.bottom = (int) (mRectSrc.top + viewHeight / zoomY);mRectDst.left = getLeft();mRectDst.top = getTop();mRectDst.right = getRight();mRectDst.bottom = getBottom();// Adjust source rectangle so that it fits within the source image.if (mRectSrc.left < 0){mRectDst.left += -mRectSrc.left * zoomX;mRectSrc.left = 0;}if (mRectSrc.right > bitmapWidth){mRectDst.right -= (mRectSrc.right - bitmapWidth) * zoomX;mRectSrc.right = bitmapWidth;}if (mRectSrc.top < 0){mRectDst.top += -mRectSrc.top * zoomY;mRectSrc.top = 0;}if (mRectSrc.bottom > bitmapHeight){mRectDst.bottom -= (mRectSrc.bottom - bitmapHeight) * zoomY;mRectSrc.bottom = bitmapHeight;}canvas.drawBitmap(mBitmap, mRectSrc, mRectDst, mPaint);}}public void update(Observable observable, Object data){invalidate();}private void calculateAspectQuotient(){if (mBitmap != null){mAspectQuotient = (((float) mBitmap.getWidth()) / mBitmap.getHeight())/ (((float) getWidth()) / getHeight());}}public void setImage(Bitmap bitmap){mBitmap = bitmap;calculateAspectQuotient();invalidate();}@Overrideprotected void onLayout(boolean changed, int left, int top, int right,int bottom){super.onLayout(changed, left, top, right, bottom);calculateAspectQuotient();}}

public class SimpleZoomListener implements View.OnTouchListener{public enum ControlType{PAN, ZOOM}@SuppressWarnings("unused")private ControlType mControlType = ControlType.PAN;private ZoomState mState;private float mX;private float mY;private float mGap;public void setZoomState(ZoomState state){mState = state;}public void setControlType(ControlType controlType){mControlType = controlType;}public boolean onTouch(View v, MotionEvent event){final int action = event.getAction();int pointCount = event.getPointerCount();if (pointCount == 1){final float x = event.getX();final float y = event.getY();switch (action){case MotionEvent.ACTION_DOWN:mX = x;mY = y;break;case MotionEvent.ACTION_MOVE:{final float dx = (x - mX) / v.getWidth();final float dy = (y - mY) / v.getHeight();mState.setPanX(mState.getPanX() - dx);mState.setPanY(mState.getPanY() - dy);mState.notifyObservers();mX = x;mY = y;break;}}}if (pointCount == 2){final float x0 = event.getX(event.getPointerId(0));final float y0 = event.getY(event.getPointerId(0));final float x1 = event.getX(event.getPointerId(1));final float y1 = event.getY(event.getPointerId(1));final float gap = getGap(x0, x1, y0, y1);switch (action){case MotionEvent.ACTION_POINTER_2_DOWN:case MotionEvent.ACTION_POINTER_1_DOWN:mGap = gap;break;case MotionEvent.ACTION_POINTER_1_UP:mX = x1;mY = y1;break;case MotionEvent.ACTION_POINTER_2_UP:mX = x0;mY = y0;break;case MotionEvent.ACTION_MOVE:{final float dgap = (gap - mGap) / mGap;// Log.d("Gap", String.valueOf(dgap));Log.d("Gap", String.valueOf((float) Math.pow(20, dgap)));mState.setZoom(mState.getZoom() * (float) Math.pow(5, dgap));mState.notifyObservers();mGap = gap;break;}}}return true;}private float getGap(float x0, float x1, float y0, float y1){return (float) Math.pow(Math.pow((x0 - x1), 2) + Math.pow((y0 - y1), 2), 0.5);}}

public class ZoomState extends Observable{private float mZoom;private float mPanX;private float mPanY;public float getPanX(){return mPanX;}public float getPanY(){return mPanY;}public float getZoom(){return mZoom;}public void setPanX(float panX){if (panX != mPanX){mPanX = panX;setChanged();}}public void setPanY(float panY){if (panY != mPanY){mPanY = panY;setChanged();}}public void setZoom(float zoom){if (zoom != mZoom){mZoom = zoom;setChanged();}}public float getZoomX(float aspectQuotient){return Math.min(mZoom, mZoom * aspectQuotient);}public float getZoomY(float aspectQuotient){return Math.min(mZoom, mZoom / aspectQuotient);}}

<?xml version="1.0" encoding="utf-8"?><LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:orientation="vertical">     <RelativeLayout  android:layout_width="fill_parent"  android:layout_height="fill_parent">     <RelativeLayout    android:id="@+id/zoomViewRelativeLayout"  android:layout_width="fill_parent"  android:layout_height="wrap_content"  android:layout_above="@+id/zoomControlRelativeLayout"  android:layout_marginBottom="2px"  >    <whu.iss.activity.ImageZoomView    android:id="@+id/zoomView"    android:layout_width="fill_parent"     android:layout_height="fill_parent"       >  </whu.iss.activity.ImageZoomView>   <ProgressBar  android:id="@+id/progress_large" android:layout_height="wrap_content" android:layout_width="wrap_content" style="?android:attr/progressBarStyleLarge" android:visibility="gone" android:layout_centerInParent="true"/>    </RelativeLayout>     <RelativeLayout      android:id="@+id/zoomControlRelativeLayout"  android:layout_width="fill_parent"  android:layout_height="50px"  android:layout_alignParentBottom="true"  >         <ZoomControls  android:id="@+id/zoomCtrl"  android:layout_width="fill_parent"  android:layout_height="fill_parent"  android:layout_centerHorizontal="true"  android:layout_centerVertical="true"  android:gravity="center"    >  </ZoomControls>      </RelativeLayout>   </RelativeLayout></LinearLayout>

工程下载地址:点击打开链接 另补充 Android Gallery3D 源码 已编译 :地址http://download.csdn.net/detail/yf210yf/4102113