展会信息港展会大全

android多点触控缩放图片及单点触控图片移动
来源:互联网   发布日期:2015-09-29 10:34:11   浏览:2260次  

导读:转载请注明原文出处:奔跑的蜗牛(袁方的技术博客)点击打开链接原始图片:点击放大按钮,或两手拖拉屏幕。上代码:public class main extends Activity { /** Called when the activity is first ......

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

原始图片:

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

上代码:

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(); } }

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();

}

}

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>

赞助本站

人工智能实验室

相关热词: 多点触控 缩放 移动

AiLab云推荐
推荐内容
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港