Android 基于手势进行图片缩放

来源:互联网 发布:优酷用户数据分析 编辑:程序博客网 时间:2024/06/17 22:00

1.触摸事件的处理

   当手指触摸屏幕时获取触摸点的个数,当触摸点只有一个时,当做平移操作处理,当触摸点为两个时则为放大缩小操作。平移操作记录下当前按下的点的坐标就行,如果是放大缩小操作,则计算出两点间的中点,后续放大和缩小以改点为中点进行.代码片段:

if(ev.getActionMasked()==MotionEvent.ACTION_DOWN||ev.getActionMasked()==MotionEvent.ACTION_POINTER_DOWN){if(!scroller.isFinished())scroller.abortAnimation();if(ev.getPointerCount()==1){downX=ev.getX();downY=ev.getY();isZooming=false;}else if(ev.getPointerCount()==2){preScale=scale;preTranslationX=translationX;//记录之前的x平移值preTranslationY=translationY;//记录前一次的y平移值touchDistance=(float) Math.hypot(ev.getX(1) - ev.getX(0), ev.getY(1) - ev.getY(0));//计算两个触摸点之间的距离touchCenterX=(ev.getX(0) + ev.getX(1)) / 2.0f;//计算中点x 坐标touchCenterY=(ev.getY(0) + ev.getY(1)) / 2.0f;//计算y的中点坐标isZooming=true;isMoving=false;}}

2.平移后计算X和Y的偏移量计算


上图中缩放点为x,y对应代码中的touchCenterX和touchCenterY,x1和Y2对应之前的边界坐标(左边和上边,上图标的有问题)在程序中对应preTranslationX和,preTranslationY。x2和Y2为缩放后新的边界坐标(左边和上边)对应代码中的translationX和translationY。代码如下

if(ev.getPointerCount()==2){//计算新的放大系数和移动的边界值scale = (float) Math.hypot(ev.getX(1) - ev.getX(0), ev.getY(1) - ev.getY(0)) / touchDistance *preScale;translationX = touchCenterX - (touchCenterX - preTranslationX) * (scale / preScale);                translationY = touchCenterY - (touchCenterY - preTranslationY) * (scale / preScale);                updateMinMax(scale);                this.invalidate();}
3.每次放大缩小后边界值计算

  放大缩小后要重新计算最大最下边界值,用于在拖动图片时防止图片被拖出边界

private void updateMinMax(float scale) {        int dw = (int) (getWidth()-scaleImgW)/2;        int dh = (int) (getHeight()-scaleImgH)/2;        if(scaleImgW*scale<getWidth()){        minX=maxX=-(int) (dw*scale-(int) (getWidth()-scaleImgW*scale)/2);        }else{        if(scaleImgW<getWidth()){        maxX=-dw*scale;        minX=getWidth()-scaleImgW*scale+maxX;        }else{        maxX=0;            minX=getWidth()-scaleImgW*scale;        }        }        if(scaleImgH*scale<getHeight()){        minY=maxY=-(int) (dh*scale-(int) (getHeight()-scaleImgH*scale)/2);        }else{        if(scaleImgH<getHeight()){        maxY=-dh*scale;        minY=getHeight()-scaleImgH*scale+maxY;        }else{        maxY=0;            minY=getHeight()-scaleImgH*scale;        }                }            }
4.拖动过程中边界值得检查

private void checkMinMax(boolean zoom) {        float moveToX = translationX;        float moveToY = translationY;        updateMinMax(scale);        if (translationX < minX) {            moveToX = minX;        } else if (translationX > maxX) {            moveToX = maxX;        }        if (translationY < minY) {            moveToY = minY;        } else if (translationY > maxY) {            moveToY = maxY;        }        animateTo(scale, moveToX, moveToY);    }

5.拖出边界后要进行还原

<span style="font-size:14px;">//放大缩小和平移动画    private void animateTo(float newScale, float newTx, float newTy, int duration) {        if (scale == newScale && translationX == newTx && translationY == newTy) {            return;        }        animateToScale = newScale;        animateToX = newTx;        animateToY = newTy;        animationStartTime = System.currentTimeMillis();        imageMoveAnimation = new AnimatorSet();        imageMoveAnimation.playTogether(ObjectAnimator.ofFloat(this, "animationValue", 0, 1));        imageMoveAnimation.setInterpolator(interpolator);        imageMoveAnimation.setDuration(duration);        imageMoveAnimation.addListener(new AnimatorListenerAdapterProxy() {            @Override            public void onAnimationEnd(Animator animation) {                imageMoveAnimation = null;                ZoomImageView.this.invalidate();            }        });        imageMoveAnimation.start();    }</span>

6.重新进行绘制

<span style="font-size:14px;">//保存画布canvas.save();//先进行平移操作canvas.translate(translationX, translationY);//再进行缩放canvas.scale(scale,scale);//进行旋转canvas.rotate(rolateDegree, getWidth()/2, getHeight()/2);//根据图片的长和宽计算绘制区域float scaleX=(float)imgW/getWidth();float scaleY=(float)imgH/getHeight();float scale=scaleX>scaleY?scaleX:scaleY;scaleImgW=(int) (imgW/scale);scaleImgH=(int) (imgH/scale);imgDrawable.setBounds(caculateDrawRect(scaleImgW, scaleImgH));imgDrawable.draw(canvas);canvas.restore();</span>


效果图:



7.项目源码下载

http://download.csdn.net/detail/xiaibiancheng/9548435

0 0
原创粉丝点击