只在别人代码的基础上做了一点点修改,限制图片超出边界,不然图片消失了不太好玩~~
1.MainActivity 显示的页面
- package whu.iss.activity;
- import android.app.Activity;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.ProgressBar;
- import android.widget.ZoomControls;
- 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() {
- @Override
- public 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();
- }
- };
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_p_w_picpath);
- mZoomView = (ImageZoomView) findViewById(R.id.zoomView);
- progressBar = (ProgressBar) findViewById(R.id.progress_large);
- progressBar.setVisibility(View.VISIBLE);
- Thread thread = new Thread(new Runnable() {
- @Override
- public void run() {
- /*
- * 加载网络图片 load form url
- */
- // mBitmap =
- // ImageDownloader.getInstance().getBitmap(url);
- mBitmap = BitmapFactory.decodeResource(
- main.this.getResources(), R.drawable.earth);
- handler.sendEmptyMessage(0);
- }
- });
- thread.start();
- ZoomControls zoomCtrl = (ZoomControls) findViewById(R.id.zoomCtrl);
- zoomCtrl.setOnZoomInClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- float z = mZoomState.getZoom() + 0.25f;
- mZoomState.setZoom(z);
- mZoomState.notifyObservers();
- }
- });
- zoomCtrl.setOnZoomOutClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- float z = mZoomState.getZoom() - 0.25f;
- mZoomState.setZoom(z);
- mZoomState.notifyObservers();
- }
- });
- }
- @Override
- protected void onDestroy() {
- super.onDestroy();
- if (mBitmap != null)
- mBitmap.recycle();
- // mZoomView.setOnTouchListener(null);
- // mZoomState.deleteObservers();
- }
- private void resetZoomState() {
- mZoomState.setPanX(0.5f);
- mZoomState.setPanY(0.5f);
- mZoomState.setZoom(1f);
- mZoomState.notifyObservers();
- }
- }
2.相对于MainActivity 的布局文件
- <?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="41dip">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerInParent="true"
- android:textSize="20sp"
- android:text="浏览图片"
- android:textColor="#ffffff">
- </TextView>
- <Button
- android:id="@+id/downBtn"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:text="下载">
- </Button>
- </RelativeLayout>
- <RelativeLayout
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <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"/>
- <ZoomControls
- android:id="@+id/zoomCtrl"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:layout_centerHorizontal="true">
- </ZoomControls>
- </RelativeLayout>
- </LinearLayout>
3.AndroidMainfest
就不写了,没啥东西,和一般的注册页面一样,没有什么权限
4.三个重要工具类
- package whu.iss.activity;
- import java.util.Observable;
- 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);
- }
- }
- package whu.iss.activity;
- import android.util.Log;
- import android.view.MotionEvent;
- import android.view.View;
- public class SimpleZoomListener implements View.OnTouchListener {
- public enum ControlType {
- PAN, ZOOM
- }
- 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();
- if (((mState.getPanX() - dx) > 0 && (mState.getPanX() - dx) < 1)
- && ((mState.getPanY() - dy) > 0 && (mState.getPanY() - dy) < 1)) {
- Log.d("dd",
- "----------------mov=" + (mState.getPanX() - dx)
- + " dy=" + (mState.getPanY() - dy));
- 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);
- }
- }
- package whu.iss.activity;
- import java.util.Observable;
- import java.util.Observer;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.Canvas;
- import android.graphics.Paint;
- import android.graphics.Rect;
- import android.util.AttributeSet;
- import android.view.View;
- 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 rectangles
- mRectSrc.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 p_w_picpath.
- 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();
- }
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
- calculateAspectQuotient();
- }
- }