android 自定義控件實現圖片縮放

public class MyImageView extends ImageView implements View.OnTouchListener
{

        public interface ImageViewVisiable
        {

              // 其他控件隱藏域顯示囘調函數
                public void visiable(int flag);
        }
        
        private ImageViewVisiable mImageViewVisiable;
        
        public void setImageViewVisiable(ImageViewVisiable imageViewVisiable)
        {
                 this.mImageViewVisiable = imageViewVisiable;
        }
        
        /**
         * 变换图片的矩阵
         */
        private Matrix matrix;

        /**
         * 记录图片矩阵状态
         */
        private Matrix saveMatrix;

        /**
         * 起始触摸点
         */
        private PointF start;

        /**
         * 触摸状态
         */
        public int MODE = MODE_INIT;

        /**
         * 初始状态,点击后隐藏标题、评论等
         */
        public static final int MODE_INIT = 1;

        /**
         * 图片为初始大小的满屏状态,未缩放,点击后显现标题、评论等
         */
        public static final int MODE_FULLSCREEN = 2;

        /**
         * 缩放状态
         */
        public static final int MODE_ZOOM = 3;

        /**
         * 拖拽状态
         */
        public static final int MODE_DRAG = 4;

        private float oldDistance;

        private float newDistance;

        private PointF midPoint;

        /**
         * 这一次手指移动后产生的缩放比例,初始是1
         */
        private float scale = 1;

        /**
         * 之前保存的缩放比例,初始是1
         */
        private float savedScale = 1;

        /**
         * 组件
         */
        
        private int mWidth;
        
        private int mHeight;
        
        private Context context;
        
        float left;
        float top;
        float right;
        float bottom;
        
        /** <默认构造函数>
         */
        public MyImageView(Context context) {
                super(context);
                init(context);
        }
        
        /** <默认构造函数>
         */
        public MyImageView(Context context,AttributeSet attrs) {
                super(context,attrs);
                init(context);
        }
        
        private void init(Context context)
        {
                this.mWidth = 400;
                this.mHeight = 400;
                this.context = context;
                matrix = new Matrix();
                saveMatrix = new Matrix();
                start = new PointF();
                midPoint = new PointF();
                setOnTouchListener(this);
        }

        private boolean getImageInfo(ImageView view)
    {
        Drawable mDrawable = null;
        if (view != null)
        {
           mDrawable =  view.getDrawable();
           if (mDrawable != null)
           {
               Rect rect = mDrawable.getBounds(); 
               float[] values = new float[9]; 
               matrix.getValues(values); 
                left = values[2];
               top = values[5];
               right = left + rect.width() * values[0];
               bottom = top + rect.height() * values[0];
           }
        }
        if (mDrawable == null)
        {
                LogUtil.d("獲取圖片失敗,請檢查是否因為內存吃緊,圖片被回收");
            return false;
        }
        return true;
    }
        
        
        public void postTranslate(MotionEvent event, ImageView view)
    {
        getImageInfo(view);
        LogUtil.d("Move获取当前图片的left:" + left + "|top:" +top + "|right:" + right + "|bottom:" + bottom);
        matrix.set(saveMatrix);

        float translateX = (event.getX() - start.x);
        float translateY = (event.getY() - start.y);
        LogUtil.d("把图片平移至:" + translateX + "x" + translateY);
        matrix.postTranslate(translateX,translateY);
    }
        
        public void stopOutScreen()
    {
        float translateX = 0;
        float translateY = 0;
        if (right > mWidth && left < 0)
        {
        }
        else
        {
            //往左
            if (right < mWidth) //当图片宽度已经大于屏幕
            {
                translateX = mWidth - right  ;
            }
            else if (left > 0)
            {
                translateX =0 - left;
            }

        }
        if (top < 0 && bottom > mHeight)
        {
        }
        else
        {
          //往上滑动
            if (top <0)
            {
                translateY =  0 - top;
            }
            else if (bottom > mHeight)
            {
                translateY = mHeight -bottom;
            }
        }
        LogUtil.d("图片还原至:" + translateX + "x" + translateY);
        matrix.postTranslate(translateX,translateY);
    }
        
        public void setPoint(PointF point, MotionEvent event)
        {
                float x = event.getX(0) + event.getX(1);
                float y = event.getY(0) + event.getY(1);
                point.set(x / 2, y / 2);

        }
        
        /**
         * 获取2个触控点距离
         * 
         * @param event
         * @return
         */
        public float caculateDistance(MotionEvent event)
        {
                float x = 0;
                float y = 0;
                try{
                        x = event.getX(0) - event.getX(1);
                        y = event.getY(0) - event.getY(1);
                }catch(IllegalArgumentException e){
                }
                return FloatMath.sqrt(x * x + y * y);
        }

        public void actionDown(ImageView v, MotionEvent event)
        {
                LogUtil.d("ACTION_DOWN  " + MODE);
                matrix.set(v.getImageMatrix());
                saveMatrix.set(matrix);
                // 得到当前点的位置
                start.set(event.getX(), event.getY());
                // 拖动
                if (savedScale > 1)
                {
                        MODE = MODE_DRAG;
                }
                getImageInfo(v);
                v.setImageMatrix(matrix);
        }
        
        public void actionMove(ImageView v, MotionEvent event)
        {
                // 拖动
                if (MODE == MODE_DRAG) {
                        postTranslate(event, v);
                }
                // 缩放
                else if (MODE == MODE_ZOOM) {

                        newDistance = caculateDistance(event);
                        if (newDistance > 5f) {
                                matrix.set(saveMatrix);
                                scale = newDistance / oldDistance;
                                matrix.postScale(scale, scale, midPoint.x, midPoint.y);
                        }
                }
                v.setImageMatrix(matrix);
        }
        
        public void actionPointerDown(ImageView v, MotionEvent event)
        {
                LogUtil.d("ACTION_POINTER_DOWN  " + MODE);
                if (MODE == MODE_FULLSCREEN || MODE == MODE_DRAG)
                {
                        oldDistance = caculateDistance(event);
                        v.setScaleType(ScaleType.MATRIX);
                        if (oldDistance > 10f)
                        {
                                saveMatrix.set(matrix);
                                setPoint(midPoint, event);
                                MODE = MODE_ZOOM;
                        }
                }
                v.setImageMatrix(matrix);
        }
        
        public void actionPointerUp(ImageView v, MotionEvent event)
        {
                LogUtil.d("ACTION_POINTER_UP  " + MODE);
        }
        
        
        public void actionUp(MotionEvent enent)
        {
                LogUtil.d("ACTION_UP  " + MODE);
                // 隐藏标题、评论
                if (MODE == MODE_INIT)
                {
                        MODE = MODE_FULLSCREEN;
                         mImageViewVisiable.visiable(GONE);
                }
                // 显示标题、评论
                else if (MODE == MODE_FULLSCREEN)
                {
                        mImageViewVisiable.visiable(VISIBLE);
                        MODE = MODE_INIT;
                }
                // 缩放
                else if (MODE == MODE_ZOOM)
                {
                        savedScale *= scale;
                        if (savedScale > 2)
                        {
                                setScaleType(ScaleType.FIT_CENTER);
                                savedScale = 1;
                                scale = 1;
                                MODE = MODE_FULLSCREEN;
                        } else if (savedScale < 1)
                        {
                                setScaleType(ScaleType.FIT_CENTER);
                                savedScale = 1;
                                scale = 1;
                                MODE = MODE_FULLSCREEN;
                        } else if (savedScale == 1)
                        {
                                MODE = MODE_FULLSCREEN;
                        }
                        
                }
                else if (MODE == MODE_DRAG)
                {
                    stopOutScreen();
                }
                setImageMatrix(matrix);
        }

        @Override
        public boolean onTouch(View v, MotionEvent event) 
        {
                ImageView view = (ImageView) v;
                switch (event.getAction() & MotionEvent.ACTION_MASK)
                {
                case MotionEvent.ACTION_DOWN:
                        
                        actionDown(view, event);
                        break;
                case MotionEvent.ACTION_MOVE:
                        
                        actionMove(view, event);
                        break;
                case MotionEvent.ACTION_POINTER_DOWN:
                        
                        actionPointerDown(view, event);
                        break;
                case MotionEvent.ACTION_POINTER_UP:
                        
                        actionPointerUp(view, event);
                        break;
                case MotionEvent.ACTION_UP:
                        
                        actionUp(event);
                        break;
                }
                return true;
        }
        
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值