最近项目有个需求,要求如果图片的宽度大于图片的高度,图片在正方形区域内可以左右移动,不能上下移动,如果图片的高度大于图片的宽度,图片在正方形区域内可以上下移动,不能左右移动。
public class ZoomImageView extends android.support.v7.widget.AppCompatImageView{ private static final int STATUS_INIT=1; private static final int STATUS_MOVE=2; private Matrix mMatrix=new Matrix(); private Bitmap sourceBitmap=null; private int currentStatus; private float currentBitmapWidth; private float currentBitmapHeight; private float lastXMove=-1; private float lastYMOve=-1; private float moveDistanceY; private float moveDistanceX; private float totalTranslateX; private float totalTranslateY; private float totalRatio; private float initRatio; private int screenWidth; public ZoomImageView(Context context) { super(context); initView(context); } public ZoomImageView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); initView(context); } public ZoomImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(context); } private void initView(Context context){ WindowManager manager= (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics metrics=new DisplayMetrics(); manager.getDefaultDisplay().getMetrics(metrics); screenWidth=metrics.widthPixels; setScaleType(ScaleType.CENTER_CROP); currentStatus=STATUS_INIT; } public void setImageBitmap(Bitmap bitmap){ sourceBitmap=bitmap; invalidate(); } @Override public boolean onTouchEvent(MotionEvent event) { if(initRatio==totalRatio){ getParent().requestDisallowInterceptTouchEvent(false); }else{ getParent().requestDisallowInterceptTouchEvent(true); } switch (event.getActionMasked()){ case MotionEvent.ACTION_MOVE: if(event.getPointerCount()==1){ float xMove=event.getX(); float yMove=event.getY(); if(lastXMove==-1&&lastYMOve==-1){ lastXMove=xMove; lastYMOve=yMove; } currentStatus=STATUS_MOVE; moveDistanceX=xMove-lastXMove; moveDistanceY=yMove-lastYMOve; if(totalTranslateX+moveDistanceX>0){ moveDistanceX=0; }else if(screenWidth-(totalTranslateX+moveDistanceX)>currentBitmapWidth){ moveDistanceX=0; } if(totalTranslateY+moveDistanceY>0){ moveDistanceY=0; }else if(screenWidth-(totalTranslateY+moveDistanceY)>currentBitmapHeight){ moveDistanceY=0; } invalidate(); lastXMove=xMove; lastYMOve=yMove; } break; case MotionEvent.ACTION_UP: lastXMove=-1; lastYMOve=-1; break; default: break; } return true; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); switch (currentStatus){ case STATUS_MOVE: move(canvas); break; case STATUS_INIT: initBitmap(canvas); break; default: if(sourceBitmap!=null){ canvas.drawBitmap(sourceBitmap,mMatrix,null); } break; } } private void move(Canvas canvas){ mMatrix.reset(); // 根据手指移动的距离计算出总偏移值 float translateX = totalTranslateX + moveDistanceX; float translateY = totalTranslateY + moveDistanceY; // 先按照已有的缩放比例对图片进行缩放 mMatrix.postScale(totalRatio, totalRatio); // 再根据移动距离进行偏移 mMatrix.postTranslate(translateX, translateY); totalTranslateX = translateX; totalTranslateY = translateY; canvas.drawBitmap(sourceBitmap, mMatrix, null); } private void initBitmap(Canvas canvas){ if (sourceBitmap != null) { mMatrix.reset(); int bitmapWidth = sourceBitmap.getWidth(); int bitmapHeigth = sourceBitmap.getHeight(); if (bitmapWidth >= bitmapHeigth) {//判断图片的宽的是否大于图片的高度 float ratio; ratio = screenWidth / (bitmapHeigth * 1.0f); mMatrix.postScale(ratio, ratio); float translateY=(screenWidth-(bitmapHeigth*ratio))/2f; mMatrix.postTranslate(0,translateY); totalTranslateY=translateY; totalRatio=initRatio=ratio; } else { float ratio; ratio = screenWidth / (bitmapWidth * 1.0f); mMatrix.postScale(ratio, ratio); float translateX = (screenWidth - (bitmapWidth * ratio)) / 2f; // 在横坐标方向上进行偏移,以保证图片居中显示 mMatrix.postTranslate(translateX, 0); totalTranslateX = translateX; totalRatio = initRatio = ratio; } currentBitmapWidth = bitmapWidth * initRatio; currentBitmapHeight = bitmapHeigth * initRatio; canvas.drawBitmap(sourceBitmap, mMatrix, null); } } }由于我这里要求的正方形区域是屏幕的宽度,