解决方案 »

  1.   

    我先把我的源码贴出来,大神们试着帮我改下吧!拜托!import java.io.IOException;
    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Matrix;
    import android.graphics.Paint;
    import android.graphics.PaintFlagsDrawFilter;
    import android.graphics.Path;
    import android.graphics.PointF;
    import android.util.AttributeSet;
    import android.util.FloatMath;
    import android.view.MotionEvent;
    import android.view.View;@SuppressLint({"NewApi", "DrawAllocation" })
    public class CustomFourImageView extends View { private int state = -1;
    private final int START = 1;

    private Bitmap topImage;
    private Bitmap bottomImage;
    private Bitmap leftImage;
    private Bitmap rightImage;

    private Paint paint;
    private Matrix topMatrix;
    private Matrix bottomMatrix;
    private Matrix leftMatrix;
    private Matrix rightMatrix;

    private float padding = 14;
    private Path top;
    private Path bottom;
    private Path left;
    private Path right;

    /** 记录是拖拉照片模式还是放大缩小照片模式 */
    private int mode = 0;// 初始状态
    /** 拖拉照片模式 */
    private static final int MODE_DRAG = 1;
    /** 放大缩小照片模式 */
    private static final int MODE_ZOOM = 2;
    /** 用于记录开始时候的坐标位置 */
    private PointF startPoint = new PointF();
    /** 两个手指的开始距离 */
    private float startDis;
    /** 两个手指的中间点 */
    private PointF midPoint;
    private static int TYPE = 0;

    public CustomFourImageView(Context context, AttributeSet attrs,
    int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    } public CustomFourImageView(Context context, AttributeSet attrs) {
    super(context, attrs);
    }

    public CustomFourImageView(Context context) {
    super(context);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right,
    int bottom) {
    super.onLayout(changed, left, top, right, bottom);
    if (state > 0) {
    return;
    }
    state = START;
    init();
    }

    /**初始化图片资源(存放于assets文件夹下)**/
    private void init() {
    setLayerType(View.LAYER_TYPE_SOFTWARE, null);// 软件加速
    try {
    topImage = BitmapFactory.decodeStream(getContext().getAssets()
    .open("m1.jpg"));
    bottomImage = BitmapFactory.decodeStream(getContext().getAssets()
    .open("m2.jpg"));
    leftImage = BitmapFactory.decodeStream(getContext().getAssets()
    .open("m3.jpg"));
    rightImage = BitmapFactory.decodeStream(getContext().getAssets()
    .open("m4.jpg"));
    } catch (IOException e) {
    e.printStackTrace();
    }
    paint = new Paint();
    paint.setAntiAlias(true);
    paint.setDither(true);// 防抖动
    paint.setFilterBitmap(true);// 过滤
    initPath();
    }

    /**画好矩阵模块**/
    private void initPath() {
    float cpad = padding / 2;// padding = 14
    // 视图宽高
    float w = getWidth();
    float h = getWidth();
    float bx = w / 2;//相当于中心点
    float by = h / 2;//相当于中心点 top = new Path();
    bottom = new Path();
    left = new Path();
    right = new Path();
    // 上图
    top.moveTo(padding, padding);
    top.lineTo(w -w/4-cpad, padding);
    top.lineTo(bx - cpad, by - cpad);
    top.lineTo(padding, h/4 - cpad);
    top.close();
    // 左图
    left.moveTo(padding, h/4 + cpad);
    left.lineTo(bx - cpad, by+cpad);
    left.lineTo(w/4 - cpad, h - padding);
    left.lineTo(padding, h - padding);
    left.close();
    // 下图
    bottom.moveTo(w/4+cpad, h-padding);
    bottom.lineTo(w -padding, h-padding);
    bottom.lineTo(w - padding, h - h/4+cpad);
    bottom.lineTo(bx+cpad, by+cpad);
    bottom.close();
    // 右图
    right.moveTo(w - w/4+cpad, padding);
    right.lineTo(w -padding, padding);
    right.lineTo(w - padding, h - h/4-cpad);
    right.lineTo(bx+cpad, by-cpad);
    right.close();
    }

    @Override
    protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if (topImage != null) {
    // 设置画板抗锯齿
    PaintFlagsDrawFilter pfd = new PaintFlagsDrawFilter(0,Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
    canvas.setDrawFilter(pfd);

    canvas.save();
    canvas.clipPath(top);// 先画好模块
    canvas.drawBitmap(topImage, topMatrix, paint);// 再画图
    canvas.restore();

    canvas.save();
    canvas.clipPath(left);
    canvas.drawBitmap(leftImage, leftMatrix, paint);
    canvas.restore(); canvas.save();
    canvas.clipPath(bottom);
    canvas.drawBitmap(bottomImage, bottomMatrix, paint);
    canvas.restore();

    canvas.save();
    canvas.clipPath(right);
    canvas.drawBitmap(rightImage, rightMatrix, paint);
    canvas.restore();
    }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction() & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN:
    // 当第一个手指按下时
    mode = MODE_DRAG;
    if (isInsideTop(event)) {
    // 上图
    TYPE = 1;
    startPoint.set(event.getX(), event.getY());
    } else if (isInsideBottom(event)) {
    // 下图
    TYPE = 2;
    startPoint.set(event.getX(), event.getY());
    } else if (isInsideLeft(event)) {
    // 左图
    TYPE = 3;
    startPoint.set(event.getX(), event.getY());
    }else if(isInsideRight(event)){
    // 右图
    TYPE = 4;
    startPoint.set(event.getX(), event.getY());
    }
    break;
    case MotionEvent.ACTION_MOVE:
    // 移动或缩放
    if (mode == MODE_DRAG) {// 拖拉图片
    int left = 0, top = 0, right = 0, bottom = 0;


    float dx = event.getX() - startPoint.x;// 减去第一次的移动距离
    float dy = event.getY() - startPoint.y;
    startPoint.x = event.getX();
    startPoint.y = event.getY();
    // 在没有移动之前的位置上进行移动
    getCurrentMatrix().postTranslate(dx, dy);
    } else if (mode == MODE_ZOOM) {// 放大缩小图片
    float endDis = distance(event);
    // 结束距离
    if (endDis > 10f) {
    // 两个手指并拢在一起的时候素大于10
    float scale = endDis / startDis;
    startDis = endDis;
    // 得到缩放倍数进行缩放
    getCurrentMatrix().postScale(scale, scale, midPoint.x,
    midPoint.y);
    }
    }
    break;
    case MotionEvent.ACTION_UP:
    // 当触点离开屏幕,但是屏幕上还有触点(手指)
    break;
    case MotionEvent.ACTION_POINTER_UP:
    mode = 0;
    break;
    case MotionEvent.ACTION_POINTER_DOWN:
    // 当屏幕上已经有触点(手指),再有一个触点压下屏幕
    mode = MODE_ZOOM;
    startDis = distance(event);
    if (startDis > 10f) { // 两个手指并拢在一起的时候像素大于10
    midPoint = mid(event);
    // 记录当前ImageView的缩放倍数
    }
    break;
    }
    invalidate();// 重绘
    return true;
    }

    /**根据TYPE值返回对应的矩阵**/
    private Matrix getCurrentMatrix() {
    switch (TYPE) {
    case 1:
    return topMatrix;
    case 2:
    return bottomMatrix;
    case 3:
    return leftMatrix;
    default:
    return rightMatrix;
    }
    }

    /**计算上图的焦点区域**/
    private boolean isInsideTop(MotionEvent event) {
    float x = event.getX();
    float y = event.getY();
    float w = getWidth();
    return y < (-2*x + 3*w/2) && y < (x/2 + w/4);
    } /**计算下图的焦点区域**/
    private boolean isInsideBottom(MotionEvent event) {
    float x = event.getX();
    float y = event.getY();
    float w = getWidth();
    return y > (-2*x + 3*w/2) && y > (x/2 + w/4);
    } /**计算左图的焦点区域**/
    private boolean isInsideLeft(MotionEvent event) {
    float x = event.getX();
    float y = event.getY();
    float w = getWidth();
    return y < (-2*x + 3*w/2) && y > (x/2 + w/4);
    }

    /**计算右图的焦点区域**/
    private boolean isInsideRight(MotionEvent event) {
    float x = event.getX();
    float y = event.getY();
    float w = getWidth();
    return y > (-2*x + 3*w/2) && y < (x/2 + w/4);
    }

    /** 计算两个手指间的距离 */
    private float distance(MotionEvent event) {
    float dx = event.getX(1) - event.getX(0);
    float dy = event.getY(1) - event.getY(0);
    //使用勾股定理返回两点之间的距离
    return FloatMath.sqrt(dx * dx + dy * dy);
    } /** 计算两个手指间的中间点 */
    private PointF mid(MotionEvent event) {
    float midX = (event.getX(1) + event.getX(0)) / 2;
    float midY = (event.getY(1) + event.getY(0)) / 2;
    return new PointF(midX, midY);
    }}
      

  2.   


    说了那么多你还没清楚,真是晕死。你把我这个源码copy一份跑起来看看,你就知道我所说的这两个问题了!帮我看看吧!哥
      

  3.   

    在init方法中加上如下四句:
                    topMatrix = new Matrix();
    bottomMatrix = new Matrix();
    leftMatrix = new Matrix();
    rightMatrix = new Matrix();我这里把原来的缩小图片方法删掉了,所以把初始化矩阵也删了。
    然后你说的那个边界问题,其实等下你试着移动图片就明白了!就是判断图片不能移出边界。还有缩小图片的时候,默认最小也要是边界大小。你看看把!我在线等你回复!
      

  4.   

    感觉楼主需要一个容器,在容器里放imageview,不要把四张图在一个imagefview里绘制出来。如果按照你现在的代码即使是实现了扩展性应该也不好的 
      

  5.   

    这样更不好做吧!单独用ImageView控件,这样的怎么布局?我现在就差添加图片时的位置,和手势越界判断,就差这两个问题没解决了。
      

  6.   


    import java.io.IOException;
    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Matrix;
    import android.graphics.Paint;
    import android.graphics.PaintFlagsDrawFilter;
    import android.graphics.Path;
    import android.graphics.PointF;
    import android.util.AttributeSet;
    import android.util.FloatMath;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.View;
     
    @SuppressLint({"NewApi", "DrawAllocation" })
    public class CustomFourImageView extends View {
     
        private int state = -1;
        private final int START = 1;
         
        private Bitmap topImage;
        private Bitmap bottomImage;
        private Bitmap leftImage;
        private Bitmap rightImage;
         
        private Paint paint;
        private Matrix topMatrix;
        private Matrix bottomMatrix;
        private Matrix leftMatrix;
        private Matrix rightMatrix;
        
        private float topMinScale = 1;
        private float bottomMinScale = 1;
        private float leftMinScale = 1;
        private float rightMinScale = 1;
         
        private float padding = 14;
        private Path top;
        private Path bottom;
        private Path left;
        private Path right;
         
        /** 记录是拖拉照片模式还是放大缩小照片模式 */
        private int mode = 0;// 初始状态
        /** 拖拉照片模式 */
        private static final int MODE_DRAG = 1;
        /** 放大缩小照片模式 */
        private static final int MODE_ZOOM = 2;
        /** 用于记录开始时候的坐标位置 */
        private PointF startPoint = new PointF();
        /** 两个手指的开始距离 */
        private float startDis;
        /** 两个手指的中间点 */
        private PointF midPoint;
        private static int TYPE = 0;
         
        public CustomFourImageView(Context context, AttributeSet attrs,
                int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
     
        public CustomFourImageView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
         
        public CustomFourImageView(Context context) {
            super(context);
        }
         
        @Override
        protected void onLayout(boolean changed, int left, int top, int right,
                int bottom) {
            super.onLayout(changed, left, top, right, bottom);
            if (state > 0) {
                return;
            }
            state = START;
            init();
            initMatrix();
        }
         
        /**初始化图片资源(存放于assets文件夹下)**/
        private void init() {
            setLayerType(View.LAYER_TYPE_SOFTWARE, null);// 软件加速
            try {
                topImage = BitmapFactory.decodeStream(getContext().getAssets()
                        .open("clip_image.png"));
                bottomImage = BitmapFactory.decodeStream(getContext().getAssets()
                        .open("down.png"));
                leftImage = BitmapFactory.decodeStream(getContext().getAssets()
                        .open("shapeBackground.png"));
                rightImage = BitmapFactory.decodeStream(getContext().getAssets()
                        .open("right.png"));
            } catch (IOException e) {
            }
            paint = new Paint();
            paint.setAntiAlias(true);
            paint.setDither(true);// 防抖动
            paint.setFilterBitmap(true);// 过滤
            initPath();
        }
         
    private void initMatrix(){
    leftMatrix = new Matrix();
    rightMatrix = new Matrix();
    topMatrix = new Matrix();
    bottomMatrix = new Matrix();

    float w = getWidth();
    float h = getHeight();

    //第一个图片
    float scaleX = w / leftImage.getWidth();
    float scaleY = h / leftImage.getHeight();
    leftMinScale = scaleX > scaleY ? scaleX : scaleY;
    leftMatrix.setScale(leftMinScale, leftMinScale);
    //第二个图片
    scaleX = w / rightImage.getWidth();
    scaleY = h / rightImage.getHeight();
    rightMinScale = scaleX > scaleY ? scaleX : scaleY;
    rightMatrix.setScale(rightMinScale, rightMinScale);
    //第三个图片
    scaleX = w / bottomImage.getWidth();
    scaleY = h / bottomImage.getHeight();
    bottomMinScale = scaleX > scaleY ? scaleX : scaleY;
    bottomMatrix.setScale(bottomMinScale, bottomMinScale);
    //第4个图片
    scaleX = w / topImage.getWidth();
    scaleY = h / topImage.getHeight();
    topMinScale = scaleX > scaleY ? scaleX : scaleY;
    topMatrix.setScale(topMinScale, topMinScale);

    }
         
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                // 当第一个手指按下时
                mode = MODE_DRAG;
                if (isInsideTop(event)) {
                    // 上图
                    TYPE = 1;
                    startPoint.set(event.getX(), event.getY());
                } else if (isInsideBottom(event)) {
                    // 下图
                    TYPE = 2;
                    startPoint.set(event.getX(), event.getY());
                } else if (isInsideLeft(event)) {
                    // 左图
                    TYPE = 3;
                    startPoint.set(event.getX(), event.getY());
                }else if(isInsideRight(event)){
                    // 右图
                    TYPE = 4;
                    startPoint.set(event.getX(), event.getY());
                }
                break;
            case MotionEvent.ACTION_MOVE:
                float[] values = new float[9];
                getCurrentMatrix().getValues(values);
                // 移动或缩放
                if (mode == MODE_DRAG) {// 拖拉图片
                    int left = 0, top = 0, right = 0, bottom = 0;
                     
                    float dx = event.getX() - startPoint.x;// 减去第一次的移动距离
                    float dy = event.getY() - startPoint.y;
                    startPoint.x = event.getX();
                    startPoint.y = event.getY();
                    // 在没有移动之前的位置上进行移动
                    Log.e("matrix ", "a: " + values[0] + " , " + values[1] + " , " + values[2]);
                    Log.e("matrix ", "b: " + values[3] + " , " + values[4] + " , " + values[5]);
                    Log.e("matrix ", "c: " + values[6] + " , " + values[7] + " , " + values[8]);
                    Log.e("matrix ", "========================");
                    
                    float maxW = (values[0] - getCurMinScale()) * getCurBitmap().getWidth();
                    float maxH = (values[0] - getCurMinScale()) * getCurBitmap().getHeight();
                    if(values[2] < 0 && dx + values[2] <= 0 && dx + values[2] > -maxW ){
                     getCurrentMatrix().postTranslate(dx, 0);
                    }
                    if(values[5] < 0 && dy + values[5] <= 0 && dy < 0 && dy + values[5] > -maxH){
                     getCurrentMatrix().postTranslate(0, dy);
                    }
                } else if (mode == MODE_ZOOM) {// 放大缩小图片
                    float endDis = distance(event);
                    // 结束距离
                    if (endDis > 10f) {
                        // 两个手指并拢在一起的时候素大于10
                        float scale = endDis / startDis;
                        startDis = endDis;
                        float oldScale = values[0];
                        if(oldScale * scale > getCurMinScale()){
                         getCurrentMatrix().postScale(scale, scale, midPoint.x,
                         midPoint.y);
                        }
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                // 当触点离开屏幕,但是屏幕上还有触点(手指)
                break;
            case MotionEvent.ACTION_POINTER_UP:
                mode = 0;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                // 当屏幕上已经有触点(手指),再有一个触点压下屏幕
                mode = MODE_ZOOM;
                startDis = distance(event);
                if (startDis > 10f) { // 两个手指并拢在一起的时候像素大于10
                    midPoint = mid(event);
                    // 记录当前ImageView的缩放倍数
                }
                break;
            }
            invalidate();// 重绘
            return true;
        }
         
        private float getCurMinScale(){
            switch (TYPE) {
            case 1:
                return topMinScale;
            case 2:
                return bottomMinScale;
            case 3:
                return leftMinScale;
            default:
                return rightMinScale;
            }
        }
        
        private Bitmap getCurBitmap(){
            switch (TYPE) {
            case 1:
                return topImage;
            case 2:
                return bottomImage;
            case 3:
                return leftImage;
            default:
                return rightImage;
            }
        }
    }贴出的代码不全,回复有字数限制,贴出的有几个新加的方法和属性。
    你先试试吧,然后自己再微调下
      

  7.   

    其实你看能不能做到这样,我前面图中不是画了对应的图片容器大小嘛,就是画了各种颜色的,它就相当于是ImageView控件的大小。当图片添加进来之后,在用户没有操作放大或缩小图片的情况下,
    1:如果图片是横着的长方形,容器也是横着的长方形,就让图片的高缩放到跟容器的高一样,然后只可以进行左右滑动。
    2:如果图片是竖着的长方形,容器是竖着的长方形,就让图片的宽缩放到跟容器的宽一样,然后只可以进行上下滑动。
    3:相反之也一样,如果容器是横着的长方形,图片也是横着的长方形,就让图片的高缩放到跟容器的高一样,然后只可以进行左右滑动。
    4:相反之也一样,如果容器是竖着的长方形,图片也是竖着的长方形,就让图片的宽缩放到跟容器的宽一样,然后只可以进行上下滑动。

    5:只有当用户进行了缩放操作之后,才可以使图片上下左右都可以进行缩放。不知道我这样说,你有没有理解。下面有一个例图:
      

  8.   

    float[] values = new float[9];
    getCurrentMatrix().getValues(values);
    这段是获取矩阵,你不用管,你只要知道 values[2]和 values[5]分别是x的位移和y的位移就行了。
    图片没动的时候, values[2]和 values[5]都是0。当缩放之后,图片的x和y变化了,这两个值也会变化。
    如下图
    缩放后values[2]和values[5]就变化为负值了,所以图片可以向右移动就是values[2] < 0 && dx + values[2] <= 0 这个判读了。
      

  9.   

    是的,因为初始化的时候已经进行了缩放         
            //第一个图片
            float scaleX = w / leftImage.getWidth();
            float scaleY = h / leftImage.getHeight();
            leftMinScale = scaleX > scaleY ? scaleX : scaleY;
            leftMatrix.setScale(leftMinScale, leftMinScale);
    将这个改下,想以宽方向为准就用leftMinScale = scaleX,高为准就leftMinScale = scaleY 。
      

  10.   

    这个位置的我弄好了,加上这个rightMatrix.postTranslate(w/2, 0);就OK了!右图的矩阵往右偏移一半(w/2)看下图:
      

  11.   


    对了,其实我想到的就是没那么复杂,只要每条边都算一下不越界就好了,就如下图,但这个还不会搞

    dx是判读移动距离的:
    values[2] < 0 && dx + values[2] <= 0 是左边的那个情况
    dx + values[2] > -maxW 是右边的情况,dx和values[2]都是负值但是最多移动距离是放大后和原来宽度的差值
      

  12.   


    if (mode == MODE_DRAG) {// 拖拉图片
    float dx = event.getX() - startPoint.x;// 减去第一次的移动距离
    float dy = event.getY() - startPoint.y;
    startPoint.x = event.getX();
    startPoint.y = event.getY();
    // 在没有移动之前的位置上进行移动
    float maxW = (values[0] - getCurMinScale()) * getCurBitmap().getWidth();
                    float maxH = (values[0] - getCurMinScale()) * getCurBitmap().getHeight();
                    
                    if(dy > 0 && dy + values[5] < 0){
                        getCurrentMatrix().postTranslate(0, dy);
                    }
                    if(dy < 0 && dy + values[5] > -maxH){
                        getCurrentMatrix().postTranslate(0, dy);
                    }
                    if(dx > 0 && values[2] + dx < 0){
                        getCurrentMatrix().postTranslate(dx, 0);
                    }
                    if(dx < 0 && values[2] + dx > -maxW){
                        getCurrentMatrix().postTranslate(dx, 0);
                    }
    }我加上了,这个还是不行的,太多问题了!你说的什么要减去滑动过后的距离,我想你是想错了,就比如说向右滑的时候,你不是减去向左滑动的距离嘛?这样是错的!你仔细看看下图:
      

  13.   


    if (mode == MODE_DRAG) {// 拖拉图片
    float dx = event.getX() - startPoint.x;// 减去第一次的移动距离
    float dy = event.getY() - startPoint.y;
    startPoint.x = event.getX();
    startPoint.y = event.getY();
    // 在没有移动之前的位置上进行移动
    float maxW = (values[0] - getCurMinScale()) * getCurBitmap().getWidth();
                    float maxH = (values[0] - getCurMinScale()) * getCurBitmap().getHeight();
                    
                    if(dy > 0 && dy + values[5] < 0){
                        getCurrentMatrix().postTranslate(0, dy);
                    }
                    if(dy < 0 && dy + values[5] > -maxH){
                        getCurrentMatrix().postTranslate(0, dy);
                    }
                    if(dx > 0 && values[2] + dx < 0){
                        getCurrentMatrix().postTranslate(dx, 0);
                    }
                    if(dx < 0 && values[2] + dx > -maxW){
                        getCurrentMatrix().postTranslate(dx, 0);
                    }
    }我加上了,这个还是不行的,太多问题了!你说的什么要减去滑动过后的距离,我想你是想错了,就比如说向右滑的时候,你不是减去向左滑动的距离嘛?这样是错的!你仔细看看下图:

    会向有移动吗?
    dx > 0 && values[2] + dx < 0会出现红色框的情况吗?
      

  14.   

    万恶的拼音啊,总是打错字。
    按你图画的,1向右移动产生的距离是大于0的。
    跟判断:
    dx > 0 && values[2] + dx < 0
    是不可能移动的,也不会出现红色框的情况。
      

  15.   

    我说的红色是图片往右移动,你先看看这3个图片的吧!从少的开始搞,这搞得我真的要疯了,怎么判断都不行。唉,气死了。@SuppressLint("NewApi")
    public class CustomTopImageView extends View { private int state = -1;
    private final int START = 1; private Bitmap topImage;
    private Bitmap leftImage;
    private Bitmap rightImage; private Paint paint;
    private Matrix topMatrix;
    private Matrix leftMatrix;
    private Matrix rightMatrix; private float padding = 10;
    private Path left;
    private Path right;
    private Path top; /** 记录是拖拉照片模式还是放大缩小照片模式 */
    private int mode = 0;// 初始状态
    /** 拖拉照片模式 */
    private static final int MODE_DRAG = 1;
    /** 放大缩小照片模式 */
    private static final int MODE_ZOOM = 2;
    /** 用于记录开始时候的坐标位置 */
    private PointF startPoint = new PointF();
    /** 两个手指的开始距离 */
    private float startDis;
    /** 两个手指的中间点 */
    private PointF midPoint;
    private static int TYPE = 0;

    private float topMinScale = 1;
        private float leftMinScale = 1;
        private float rightMinScale = 1;
        private int excessImageH=0;//图片超出矩阵部分高度;
        private int excessImageW = 0;//图片超出矩阵部分宽度;
        private float scaleX = 0; public CustomTopImageView(Context context, AttributeSet attrs,
    int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    } public CustomTopImageView(Context context, AttributeSet attrs) {
    super(context, attrs);
    } public CustomTopImageView(Context context) {
    super(context);
    } @Override
    protected void onLayout(boolean changed, int left, int top, int right,
    int bottom) {
    super.onLayout(changed, left, top, right, bottom);
    if (state > 0) {
    return;
    }
    state = START;
    init();
    } private void init() {
    setLayerType(View.LAYER_TYPE_SOFTWARE, null);// 软件加速
    try {
    leftImage = BitmapFactory.decodeStream(getContext().getAssets()
    .open("m1.jpg"));
    rightImage = BitmapFactory.decodeStream(getContext().getAssets()
    .open("m2.jpg"));
    topImage = BitmapFactory.decodeStream(getContext().getAssets()
    .open("m3.jpg"));
    } catch (IOException e) {
    e.printStackTrace();
    }
    paint = new Paint();
    paint.setAntiAlias(true);
    paint.setDither(true);// 防抖动
    paint.setFilterBitmap(true);// 过滤
    initMatrix();// 缩小图片
    initPath();
    }// // 初始化矩阵(3X3)并缩放图片
    // private void initMatrix() {
    // leftMatrix = new Matrix();
    // rightMatrix = new Matrix();
    // topMatrix = new Matrix();
    // float w = getWidth();
    // float h = getWidth();
    //
    // setImageZoom(leftMatrix,w/2,h,leftImage);
    // setImageZoom(rightMatrix,w/2,h,rightImage);
    // setImageZoom(topMatrix,w,h/2,topImage);
    //
    // rightMatrix.postTranslate(w/2, 0);//矩阵偏移
    // } private void initMatrix(){
            leftMatrix = new Matrix();
            rightMatrix = new Matrix();
            topMatrix = new Matrix();
             
            float w = getWidth();
            float h = getHeight();
            //第一个图片
            scaleX = w / leftImage.getWidth();
            float scaleY = h / leftImage.getHeight();
            leftMinScale = scaleX > scaleY ? scaleX : scaleY;
            leftMatrix.setScale(leftMinScale, leftMinScale);
            //第二个图片
            scaleX = w / rightImage.getWidth();
            scaleY = h / rightImage.getHeight();
            rightMinScale = scaleX > scaleY ? scaleX : scaleY;
            rightMatrix.setScale(rightMinScale, rightMinScale);
            //第三个图片
            scaleX = w / topImage.getWidth();
            scaleY = h / topImage.getHeight();
            topMinScale = scaleX > scaleY ? scaleX : scaleY;
            topMatrix.setScale(topMinScale, topMinScale);
            
            rightMatrix.postTranslate(w/2, 0);//右图矩阵偏移
        }


    /**
     * 根据矩阵的形状动态缩放图片
     * @param matrix 矩阵
     * @param matrixW 控件宽度
     * @param matrixH 控件高度
     * @param bmp 图片
     */
    private void setImageZoom(Matrix matrix,float matrixW,float matrixH,Bitmap bmp){
    float imgW = bmp.getWidth();
    float imgH = bmp.getHeight();
    //得出比例
    float w = matrixW/imgW;
    float h = matrixH/imgH;

    if(matrixW < matrixH){
    matrix.setScale(h, h);
    }else{
    matrix.setScale(w, w);
    }
    }

    // 画好矩阵模块
    private void initPath() {
    float cpad = padding / 2;// padding = 10
    // 视图宽高
    float w = getWidth();
    float h = getWidth();
    float bx = w / 2;//
    float by = h / 2;// 相当于中心点 top = new Path();
    left = new Path();
    right = new Path();
    // 上图
    top.moveTo(padding * 1.7f, padding);
    top.lineTo(w - padding * 1.7f, padding);
    top.lineTo(bx, by - 0.7f * padding);
    top.close();
    // 左图
    left.moveTo(padding, padding * 1.7f);
    left.lineTo(bx - cpad, by + 0.2f * padding);
    left.lineTo(bx - cpad, h - padding);
    left.lineTo(padding, h - padding);
    left.close();
    // 右图
    right.moveTo(w - padding, padding * 1.7f);
    right.lineTo(bx + cpad, by + 0.2f * padding);
    right.lineTo(bx + cpad, h - padding);
    right.lineTo(w - padding, h - padding);
    right.close();
    } @Override
    protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if (topImage != null) {
    // 设置抗锯齿
    PaintFlagsDrawFilter pfd = new PaintFlagsDrawFilter(0,Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
    canvas.setDrawFilter(pfd);
    canvas.save();
    canvas.clipPath(top);// 先画好模块
    canvas.drawBitmap(topImage, topMatrix, paint);// 再画图
    canvas.restore(); canvas.save();
    canvas.clipPath(left);
    canvas.drawBitmap(leftImage, leftMatrix, paint);
    canvas.restore(); canvas.save();
    canvas.clipPath(right);
    canvas.drawBitmap(rightImage, rightMatrix, paint);
    canvas.restore();
    }
    } @Override
    public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction() & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN:
    // 当第一个手指按下时
    mode = MODE_DRAG;
    if (isInsideTop(event)) {
    // 上图
    TYPE = 1;
    startPoint.set(event.getX(), event.getY());
    } else if (isInsideLeft(event)) {
    // 左图
    TYPE = 2;
    startPoint.set(event.getX(), event.getY());
    } else if (isInsideRight(event)) {
    // 右图
    TYPE = 3;
    startPoint.set(event.getX(), event.getY());
    }
    break;
    case MotionEvent.ACTION_MOVE:
    // 移动或缩放
    float[] values = new float[9];//拿到矩阵中的元素
    getCurrentMatrix().getValues(values);//获取图片3x3矩阵
    if (mode == MODE_DRAG) {// 拖拉图片
    float dx = event.getX() - startPoint.x;//减去第一次的移动距离
    float dy = event.getY() - startPoint.y;
    startPoint.x = event.getX();
    startPoint.y = event.getY();
    //往上移动
                    if(dy < 0 && dy + values[5] > excessImageH){
                        getCurrentMatrix().postTranslate(0, dy);
                    }
                    //往下移动
                    if(dy > 0 && dy + values[5] < -excessImageH){
                        getCurrentMatrix().postTranslate(0, dy);
                    }
                    //往左移动
                    if(dx > 0 && values[2]+dx < -excessImageW){
                        getCurrentMatrix().postTranslate(dx, 0);
                    }
                    //往右移动
                    if(dx < 0 && values[2]+dx > excessImageW){
                        getCurrentMatrix().postTranslate(dx, 0);
                    }
    } else if (mode == MODE_ZOOM) {// 放大缩小图片
    float endDis = distance(event);
    // 结束距离
    if (endDis > 10f) {
    // 两个手指并拢在一起的时候素大于10
    float scale = endDis / startDis;
    startDis = endDis;
    float oldScale = values[0];
    // 得到缩放倍数进行缩放
    if(oldScale * scale > getCurMinScale()){
                            getCurrentMatrix().postScale(scale, scale, midPoint.x,midPoint.y);
                        }
    }
    }
    break;
    case MotionEvent.ACTION_UP:
    // 当触点离开屏幕,但是屏幕上还有触点(手指)
    break;
    case MotionEvent.ACTION_POINTER_UP:
    mode = 0;
    break;
    case MotionEvent.ACTION_POINTER_DOWN:
    // 当屏幕上已经有触点(手指),再有一个触点压下屏幕
    mode = MODE_ZOOM;
    startDis = distance(event);
    if (startDis > 10f) { // 两个手指并拢在一起的时候像素大于10
    midPoint = mid(event);
    // 记录当前ImageView的缩放倍数
    }
    break;
    }
    invalidate();// 重绘
    return true;
    } /**根据TYPE值返回对应的矩阵*/
    private Matrix getCurrentMatrix() {
    switch (TYPE) {
    case 1:
    excessImageH = (topImage.getHeight()*(int)topMinScale)-(getHeight()/2);
    excessImageW = (topImage.getWidth()*(int)topMinScale)-getWidth();
    return topMatrix;
    case 2:
    excessImageH = (leftImage.getHeight()*(int)leftMinScale)-getHeight();
    excessImageW = (leftImage.getWidth()*(int)leftMinScale)-(getWidth()/2);
    return leftMatrix;
    default:
    excessImageH = (rightImage.getHeight()*(int)rightMinScale)-getHeight();
    excessImageW = (rightImage.getWidth()*(int)rightMinScale)-(getWidth()/2);
    return rightMatrix;
    }
    } /**根据TYPE值返回对应的缩放系数*/
    private float getCurMinScale(){
            switch (TYPE) {
            case 1:
                return topMinScale;
            case 2:
                return leftMinScale;
            default:
                return rightMinScale;
            }
        } private boolean isInsideTop(MotionEvent event) {
    float x = event.getX();
    float y = event.getY();
    float w = getWidth();
    float h = getWidth();
    float by = h / 2;
    return y < by && y < (h - h * x / w) && y < x;
    } private boolean isInsideLeft(MotionEvent event) {
    float x = event.getX();
    float y = event.getY();
    float w = getWidth();
    float bx = w / 2;
    return x < bx && y > x;
    } private boolean isInsideRight(MotionEvent event) {
    float x = event.getX();
    float y = event.getY();
    float w = getWidth();
    float h = getWidth();
    float bx = w / 2;
    return x > bx && y > (h - h * x / w);
    } /** 计算两个手指间的距离 */
    private float distance(MotionEvent event) {
    float dx = event.getX(1) - event.getX(0);
    float dy = event.getY(1) - event.getY(0);
    /** 使用勾股定理返回两点之间的距离 */
    return FloatMath.sqrt(dx * dx + dy * dy);
    } /** 计算两个手指间的中间点 */
    private PointF mid(MotionEvent event) {
    float midX = (event.getX(1) + event.getX(0)) / 2;
    float midY = (event.getY(1) + event.getY(0)) / 2;
    return new PointF(midX, midY);
    }
    }