zoukankan      html  css  js  c++  java
  • 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() + "" + 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;
                }
            }
        };
    }
  • 相关阅读:
    Count Complete Tree Nodes***
    Kth Smallest Element in a BST
    Lowest Common Ancestor of a Binary Search Tree
    VPC实验案例
    BGP实验 (IBGP,EBGP) neighbor
    BGP基础实验 Cyrus
    H3c AC模式切换
    语音实验8 硬件电话通过DHCP方式连接到CME
    语音实验7 2台CME,3台软件电话
    语音实验6 1台CME,2台软件电话
  • 原文地址:https://www.cnblogs.com/blogzhangwei/p/4462369.html
Copyright © 2011-2022 走看看