Android 图片的放大缩小拖拉
package com.example.ImageView; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.*; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.FloatMath; import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; /** * Created by Administrator on 2015/1/4. * <p/> * 实现图片缩小放大拖拉效果 */ public class MImageView extends View { private Paint mPaint;//画笔 private Drawable mDrawable; private Rect mDrawableRect = new Rect(); private Rect mRect = new Rect();//原始图片位置大小 private Context mContext; private float mRation_WH = 0; private float mOldX = 0, mOldY = 0; private boolean isFirst = true; private int SINGALDOWN = 1;// 单点按下 private int mStatus = 0; private int offsetWidth = 0; private int offsetHeight = 0; private GestureDetector tapDetector;//实现双击放大缩小功能 private float beforeLenght, afterLenght;// 两触点距离 private float scale_temp = 1;// 缩放比例 private MODE mode = MODE.NONE; private OnMeasureListener onMeasureListener; private boolean status = true; public MImageView(Context context) { super(context); Init(context); } public MImageView(Context context, AttributeSet attrs) { super(context, attrs); Init(context); } public void setOnMeasureListener(OnMeasureListener onMeasureListener) { this.onMeasureListener = onMeasureListener; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (getMeasuredWidth() > 0 && getMeasuredHeight() > 0 && status) { if (onMeasureListener != null) { onMeasureListener.onMeasureSize(getMeasuredWidth(), getMeasuredHeight()); status = false; } } } public interface OnMeasureListener { public void onMeasureSize(int width, int height); } private void Init(Context context) {//初始化控件属性 this.mContext = context; mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setColor(Color.BLACK); mPaint.setStyle(Paint.Style.FILL); mPaint.setTextSize(35.0f); tapDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() { @Override public boolean onDoubleTap(MotionEvent e) { doScaleAnim(); return true; } }); } @SuppressLint("DrawAllocation") @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); try { if (mDrawable == null || mDrawable.getIntrinsicHeight() == 0 || mDrawable.getIntrinsicWidth() == 0) { return; } setBounds(); mDrawable.draw(canvas); } catch (Exception e) { } } /** * 模式 NONE:无 DRAG:拖拽. ZOOM:缩放 * * @author zhangjia */ private enum MODE { NONE, DRAG, ZOOM } @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub if (!tapDetector.onTouchEvent(event)) { switch (event.getAction() & event.getActionMasked()) { case MotionEvent.ACTION_DOWN: mStatus = SINGALDOWN; mOldX = event.getX(); mOldY = event.getY(); mode = MODE.DRAG; break; case MotionEvent.ACTION_POINTER_DOWN: mode = MODE.ZOOM; beforeLenght = getDistance(event);// 获取两点的距离 break; case MotionEvent.ACTION_POINTER_UP: mOldX = event.getX(); mOldX = event.getY(); mode = MODE.NONE; break; case MotionEvent.ACTION_UP: if (mDrawableRect.height() < mRect.height() && mDrawableRect.width() < mRect.width()) doScaleAnim(); else { up(); invalidate(); } getParent().requestDisallowInterceptTouchEvent(false); mStatus = 0; mode = MODE.NONE; break; case MotionEvent.ACTION_MOVE: if (mode == MODE.DRAG) {//移动状态 if (getWidth() < mDrawableRect.width()) { getParent().requestDisallowInterceptTouchEvent(true); moveDrag(event); } else { getParent().requestDisallowInterceptTouchEvent(false); return false; } } if (mode == MODE.ZOOM) {//判断是否为缩放状态 getParent().requestDisallowInterceptTouchEvent(true); moveZoom(event); } Log.i("wade", mDrawableRect.toString() + "width:" + getWidth() + "height:" + getHeight()); break; default: break; } } else { return false; } return true; } /** * 获取两点的距离 * */ float getDistance(MotionEvent event) { float x = event.getX(0) - event.getX(1); float y = event.getY(0) - event.getY(1); return FloatMath.sqrt(x * x + y * y); } /** * 手指抬起的时候回弹边界* */ private void up() { int left, right, top, bottom; left = mDrawableRect.left; right = mDrawableRect.right; top = mDrawableRect.top; bottom = mDrawableRect.bottom; offsetWidth = 0; offsetHeight = 0; if (mDrawableRect.width() > getWidth() && mDrawableRect.left >= 0) { offsetWidth = -mDrawableRect.left; } if (mDrawableRect.height() > getHeight() && mDrawableRect.top >= 0) { offsetHeight = -mDrawableRect.top; } if (mDrawableRect.width() > getWidth() && mDrawableRect.right <= getWidth()) { offsetWidth = getWidth() - mDrawableRect.right; } if (mDrawableRect.height() > getHeight() && mDrawableRect.bottom <= getHeight()) { offsetHeight = getHeight() - mDrawableRect.bottom; } if (mDrawableRect.width() < getWidth()) { left = (getWidth() - mDrawableRect.width()) / 2; offsetWidth = 0; mDrawableRect.set(left, top, left + mDrawableRect.width(), bottom); } if (mDrawableRect.height() < getHeight()) { top = (getHeight() - mDrawableRect.height()) / 2; offsetHeight = 0; mDrawableRect.set(left, top, right, top + mDrawableRect.height()); } mDrawableRect.offset(offsetWidth, offsetHeight); } private void moveDrag(MotionEvent event) { if (mStatus == SINGALDOWN) { offsetWidth = (int) (event.getX() - mOldX); offsetHeight = (int) (event.getY() - mOldY); mOldX = event.getX(); mOldY = event.getY(); if (mDrawableRect.width() < getWidth()) { offsetWidth = 0; } if (mDrawableRect.height() < getHeight()) { offsetHeight = 0; } mDrawableRect.offset(offsetWidth, offsetHeight); invalidate(); } } private void moveZoom(MotionEvent event) {//用于缩放布局的方法 afterLenght = getDistance(event);// 获取两点的距离 float gapLenght = afterLenght - beforeLenght;// 变化的长度 if (Math.abs(gapLenght) > 5f) { scale_temp = afterLenght / beforeLenght;// 求的缩放的比例 } Log.i("wade", "gapLenght" + gapLenght + ""); int disX = (int) (mDrawableRect.width() * Math.abs(1 - scale_temp)) / 4;// 获取缩放水平距离 int disY = (int) (mDrawableRect.height() * Math.abs(1 - scale_temp)) / 4;// 获取缩放垂直距离 if (beforeLenght < afterLenght) { if (scale_temp > 1 && mDrawableRect.width() < mContext.getResources() .getDisplayMetrics().widthPixels * 3) { mDrawableRect.set(mDrawableRect.left - disX, mDrawableRect.top - disY, mDrawableRect.right + disX, mDrawableRect.bottom + disY); invalidate(); } } else { if (scale_temp < 1 && mDrawableRect.width() > mContext.getResources() .getDisplayMetrics().widthPixels / 2) { mDrawableRect.set(mDrawableRect.left + disX, mDrawableRect.top + disY, mDrawableRect.right - disX, mDrawableRect.bottom - disY); invalidate(); } } beforeLenght = afterLenght; scale_temp = 1; } /** * 设置mDrawable的位置* */ public void setBounds() { if (isFirst) { mRation_WH = (float) mDrawable.getIntrinsicWidth() / (float) mDrawable.getIntrinsicHeight(); int px_w = Math.min(getWidth(), dip2px(mContext, mDrawable.getIntrinsicWidth())); int px_h = (int) (px_w / mRation_WH); int left = (getWidth() - px_w) / 2; int top = (getHeight() - px_h) / 2; int right = px_w + left; int bottom = px_h + top; mRect.set(left, top, right, bottom); mDrawableRect.set(left, top, right, bottom); isFirst = false; } mDrawable.setBounds(mDrawableRect); } public Drawable getMDrawable() { return mDrawable; } public void setMDrawable(Drawable mDrawable) { this.mDrawable = mDrawable; postInvalidate(); } public void setImageBitmap(Bitmap mBitmap) { if (mBitmap != null) { setMDrawable(new BitmapDrawable(getResources(), mBitmap)); } } public void setMDrawable(Drawable mDrawable, Rect rect) { this.mDrawable = mDrawable; postInvalidate();//第一次post为了计算图片的大小和位置 if (rect != null) { mDrawableRect.set(rect); postInvalidate(); doScaleAnim(); } } public void setImageBitmap(Bitmap mBitmap, Rect rect) { if (mBitmap != null) { setMDrawable(new BitmapDrawable(getResources(), mBitmap), rect); } } public int dip2px(Context context, int value) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (value * scale + 0.5f); } /** * 缩放动画处理 */ public void doScaleAnim() { MyAsyncTask myAsyncTask = new MyAsyncTask(); myAsyncTask.execute(); } /** * 回缩动画執行 */ class MyAsyncTask extends AsyncTask<Void, Integer, Void> { private int current_Width, current_Height, width; private int left, top, right, bottom; private float scale_WH;// 宽高的比例 private float STEP = 8f;// 步伐 private float step_H, step_V;// 水平步伐,垂直步伐 private int status;//1放大到MAX_W宽度,2缩小原始大小,3放大成原始大小 private boolean change = true;//用来检测是否还能缩放 public MyAsyncTask() { } @Override protected Void doInBackground(Void... params) { change = true; current_Width = mDrawableRect.width(); current_Height = mDrawableRect.height(); scale_WH = (float) current_Height / current_Width; step_H = STEP; step_V = scale_WH * STEP; left = mDrawableRect.left; top = mDrawableRect.top; right = mDrawableRect.right; bottom = mDrawableRect.bottom; if (mDrawableRect.height() == mRect.height() && mDrawableRect.width() == mRect.width()) { status = 1; width = mRect.width() * 2; } else { if (mDrawableRect.height() > mRect.height() && mDrawableRect.width() > mRect.width()) { status = 2; width = mRect.width(); } else { if (mDrawableRect.height() < mRect.height() && mDrawableRect.width() < mRect.width()) { status = 3; width = mRect.width(); } } } while (change) { switch (status) { case 1: left -= step_H; top -= step_V; right += step_H; bottom += step_V; current_Width += 2 * step_H; if (current_Width >= width) change = false; break; case 2: left += step_H; top += step_V; right -= step_H; bottom -= step_V; current_Width -= 2 * step_H; if (current_Width <= width) { left = mRect.left; top = mRect.top; right = mRect.right; bottom = mRect.bottom; change = false; } break; case 3: left -= step_H; top -= step_V; right += step_H; bottom += step_V; current_Width += 2 * step_H; if (current_Width >= width) { left = mRect.left; top = mRect.top; right = mRect.right; bottom = mRect.bottom; change = false; } break; } mDrawableRect.set(left, top, right, bottom); Message.obtain(handler, 1).sendToTarget(); try { Thread.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } } return null; } @Override protected void onProgressUpdate(final Integer... values) { super.onProgressUpdate(values); } @Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); up(); invalidate(); } } Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 1: invalidate(); break; } } }; }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。