原始图片:
点击放大按钮,或两手拖拉屏幕。
上代码:
- <span style="font-size:13px;"></span><pre name="code" class="java">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.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()
- {
- @Override
- public 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()
- {
- @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();
- }
- private void resetZoomState()
- {
- mZoomState.setPanX(0.5f);
- mZoomState.setPanY(0.5f);
- mZoomState.setZoom(1f);
- mZoomState.notifyObservers();
- }
- }</pre><br>
- <pre name="code" class="java">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 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();
- }
- @Override
- protected void onLayout(boolean changed, int left, int top, int right,
- int bottom)
- {
- super.onLayout(changed, left, top, right, bottom);
- calculateAspectQuotient();
- }
- }
- </pre><br>
- <pre name="code" class="java">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);
- }
- }</pre><br>
- <pre name="code" class="java">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);
- }
- }</pre><br>
- <pre name="code" class="java"><?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></pre><br>
- 工程下载地址:<a href="http://download.csdn.net/detail/yf210yf/4102077">点击打开链接</a> 另补充 Android Gallery3D 源码 已编译 :地址<a href="http://download.csdn.net/detail/yf210yf/4102113">http://download.csdn.net/detail/yf210yf/4102113</a><span style="white-space:pre; background-color:rgb(240,240,240)"></span><pre name="code" class="java"></pre>
- <pre></pre>