返回
顶部

修改密码

android多点触控缩放图片及单点触控图片移动

+1

-1

收藏

+1

-1

点赞0

评论0

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

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

原始图片:

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

上代码:

 

 

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>

扫一扫在手机打开

评论
已有0条评论
0/150
提交
热门评论
相关推荐
今日要闻
换一批
热点排行