Android实现 通过手势拖动缩放图片
1)在activity_main.xml里面添加图片控件
<?xml version="1.0" encoding="utf-8"?>
<com.teleca.moveandgesturepic.ImageZoomView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/zoomview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
2编写主Activity文件,监听用户选择的设置
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
/**
* Activity for zoom tutorial 1
*/
public class MainActivity extends Activity {
/** Constant used as menu item id for setting zoom control type */
private static final int MENU_ID_ZOOM = 0;
/** Constant used as menu item id for setting pan control type */
private static final int MENU_ID_PAN = 1;
/** Constant used as menu item id for resetting zoom state */
private static final int MENU_ID_RESET = 2;
/** Image zoom view */
private ImageZoomView mZoomView;
/** Zoom state */
private ZoomState mZoomState;
/** Decoded bitmap image */
private Bitmap mBitmap;
/** On touch listener for zoom view */
private SimpleZoomListener mZoomListener;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mZoomState = new ZoomState();
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.iamge800x532);
mZoomListener = new SimpleZoomListener();
mZoomListener.setZoomState(mZoomState);
mZoomView = (ImageZoomView)findViewById(R.id.zoomview);
mZoomView.setZoomState(mZoomState);
mZoomView.setImage(mBitmap);
mZoomView.setOnTouchListener(mZoomListener);
resetZoomState();
}
@Override
protected void onDestroy() {
super.onDestroy();
mBitmap.recycle();
mZoomView.setOnTouchListener(null);
mZoomState.deleteObservers();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(Menu.NONE, MENU_ID_ZOOM, 0, R.string.menu_zoom);
menu.add(Menu.NONE, MENU_ID_PAN, 1, R.string.menu_pan);
menu.add(Menu.NONE, MENU_ID_RESET, 2, R.string.menu_reset);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_ID_ZOOM:
mZoomListener.setControlType(SimpleZoomListener.ControlType.ZOOM);
break;
case MENU_ID_PAN:
mZoomListener.setControlType(SimpleZoomListener.ControlType.PAN);
break;
case MENU_ID_RESET:
resetZoomState();
break;
}
return super.onOptionsItemSelected(item);
}
/**
* Reset zoom state and notify observers
*/
private void resetZoomState() {
mZoomState.setPanX(0.5f);
mZoomState.setPanY(0.5f);
mZoomState.setZoom(1f);
mZoomState.notifyObservers();
}
}
3获取并设置移动位置和缩放值
import java.util.Observable;
/**
* A ZoomState holds zoom and pan values and allows the user to read and listen
* to changes. Clients that modify ZoomState should call notifyObservers()
*/
public class ZoomState extends Observable {
/**
* Zoom level A value of 1.0 means the content fits the view.
*/
private float mZoom;
/**
* Pan position x-coordinate X-coordinate of zoom window center position,
* relative to the width of the content.
*/
private float mPanX;
/**
* Pan position y-coordinate Y-coordinate of zoom window center position,
* relative to the height of the content.
*/
private float mPanY;
// Public methods
/**
* Get current x-pan
*
* @return current x-pan
*/
public float getPanX() {
return mPanX;
}
/**
* Get current y-pan
*
* @return Current y-pan
*/
public float getPanY() {
return mPanY;
}
/**
* Get current zoom value
*
* @return Current zoom value
*/
public float getZoom() {
return mZoom;
}
/**
* Help function for calculating current zoom value in x-dimension
*
* @param aspectQuotient (Aspect ratio content) / (Aspect ratio view)
* @return Current zoom value in x-dimension
*/
public float getZoomX(float aspectQuotient) {
return Math.min(mZoom, mZoom * aspectQuotient);
}
/**
* Help function for calculating current zoom value in y-dimension
*
* @param aspectQuotient (Aspect ratio content) / (Aspect ratio view)
* @return Current zoom value in y-dimension
*/
public float getZoomY(float aspectQuotient) {
return Math.min(mZoom, mZoom / aspectQuotient);
}
/**
* Set pan-x
*
* @param panX Pan-x value to set
*/
public void setPanX(float panX) {
if (panX != mPanX) {
mPanX = panX;
setChanged();
}
}
/**
* Set pan-y
*
* @param panY Pan-y value to set
*/
public void setPanY(float panY) {
if (panY != mPanY) {
mPanY = panY;
setChanged();
}
}
/**
* Set zoom
*
* @param zoom Zoom value to set
*/
public void setZoom(float zoom) {
if (zoom != mZoom) {
mZoom = zoom;
setChanged();
}
}
}
import android.view.MotionEvent;
import android.view.View;
/**
* Simple on touch listener for zoom view
*/
public class SimpleZoomListener implements View.OnTouchListener {
/**
* Which type of control is used
*/
public enum ControlType {
PAN, ZOOM
}
/** State being controlled by touch events */
private ZoomState mState;
/** Current control type being used */
private ControlType mControlType = ControlType.ZOOM;
/** X-coordinate of previously handled touch event */
private float mX;
/** Y-coordinate of previously handled touch event */
private float mY;
/**
* Sets the zoom state that should be controlled
*
* @param state Zoom state
*/
public void setZoomState(ZoomState state) {
mState = state;
}
/**
* Sets the control type to use
*
* @param controlType Control type
*/
public void setControlType(ControlType controlType) {
mControlType = controlType;
}
// implements View.OnTouchListener
public boolean onTouch(View v, MotionEvent event) {
final int action = event.getAction();
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 (mControlType == ControlType.ZOOM) {
mState.setZoom(mState.getZoom() * (float)Math.pow(20, -dy));
mState.notifyObservers();
} else {
mState.setPanX(mState.getPanX() - dx);
mState.setPanY(mState.getPanY() - dy);
mState.notifyObservers();
}
mX = x;
mY = y;
break;
}
}
return true;
}
}
实现效果图: