设置图片在正方形区域内左右上下移动

最近项目有个需求,要求如果图片的宽度大于图片的高度,图片在正方形区域内可以左右移动,不能上下移动,如果图片的高度大于图片的宽度,图片在正方形区域内可以上下移动,不能左右移动。

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);
            }
        }

}
由于我这里要求的正方形区域是屏幕的宽度,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值