android-如何将图像移动到此CustomImageVIew的中心

时间:2014-06-09 12:15:34

标签: android android-imageview

我需要能够在imageView中缩放图像。

我已经搜索并使用了这个CustomImageVIew,它运行正常。

唯一的问题是,它将图像移动到屏幕的左上角。

抱歉,我无法发布截图,请考虑一下,它位于左上角屏幕的1/4处。

我想让图像到达屏幕的中心

这是班级:

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

public class CustomImageVIew extends ImageView implements OnTouchListener {


private Matrix matrix = new Matrix();
private Matrix savedMatrix = new Matrix();

static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;

private int mode = NONE;

private PointF mStartPoint = new PointF();
private PointF mMiddlePoint = new PointF();
private Point mBitmapMiddlePoint = new Point();

private float oldDist = 1f;
private float matrixValues[] = {0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f};
private float scale;
private float oldEventX = 0;
private float oldEventY = 0;
private float oldStartPointX = 0;
private float oldStartPointY = 0;
private int mViewWidth = -1;
private int mViewHeight = -1;
private int mBitmapWidth = -1;
private int mBitmapHeight = -1;
private boolean mDraggable = false;


public CustomImageVIew(Context context) {
    this(context, null, 0);
}

public CustomImageVIew(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public CustomImageVIew(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    this.setOnTouchListener(this);
}

@Override
public void onSizeChanged (int w, int h, int oldw, int oldh){
    super.onSizeChanged(w, h, oldw, oldh);
    mViewWidth = w;
    mViewHeight = h;
}

public void setBitmap(Bitmap bitmap){
    if(bitmap != null){
        setImageBitmap(bitmap);

        mBitmapWidth = bitmap.getWidth();
        mBitmapHeight = bitmap.getHeight();
        mBitmapMiddlePoint.x = (mViewWidth / 2) - (mBitmapWidth /  2);
        mBitmapMiddlePoint.y = (mViewHeight / 2) - (mBitmapHeight / 2);

        matrix.postTranslate(mBitmapMiddlePoint.x, mBitmapMiddlePoint.y);
        this.setImageMatrix(matrix);
    }
}

@Override
public boolean onTouch(View v, MotionEvent event){
    switch (event.getAction() & MotionEvent.ACTION_MASK) {
    case MotionEvent.ACTION_DOWN:
        savedMatrix.set(matrix);
        mStartPoint.set(event.getX(), event.getY());
        mode = DRAG;
        break;
    case MotionEvent.ACTION_POINTER_DOWN:
        oldDist = spacing(event);
        if(oldDist > 10f){
            savedMatrix.set(matrix);
            midPoint(mMiddlePoint, event);
            mode = ZOOM;
        }
        break;
    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_POINTER_UP:
        mode = NONE;
        break;
    case MotionEvent.ACTION_MOVE:
        if(mode == DRAG){
            drag(event);
        } else if(mode == ZOOM){
            zoom(event);
        } 
        break;
    }

    return true;


  }



   public void drag(MotionEvent event){
       matrix.getValues(matrixValues);
   float left = matrixValues[2];
   float top = matrixValues[5];
   float bottom = (top + (matrixValues[0] * mBitmapHeight)) - mViewHeight;
   float right = (left + (matrixValues[0] * mBitmapWidth)) -mViewWidth;

   float eventX = event.getX();
   float eventY = event.getY();
   float spacingX = eventX - mStartPoint.x;
   float spacingY = eventY - mStartPoint.y;
   float newPositionLeft = (left  < 0 ? spacingX : spacingX * -1) + left;
   float newPositionRight = (spacingX) + right;
   float newPositionTop = (top  < 0 ? spacingY : spacingY * -1) + top;
   float newPositionBottom = (spacingY) + bottom;
   boolean x = true;
   boolean y = true;

   if(newPositionRight < 0.0f || newPositionLeft > 0.0f){
       if(newPositionRight < 0.0f && newPositionLeft > 0.0f){
           x = false;
       } else{
           eventX = oldEventX;
           mStartPoint.x = oldStartPointX;
       }
   }
   if(newPositionBottom < 0.0f || newPositionTop > 0.0f){
       if(newPositionBottom < 0.0f && newPositionTop > 0.0f){
           y = false;
       } else{
           eventY = oldEventY;
           mStartPoint.y = oldStartPointY;
       }
   }

   if(mDraggable){
       matrix.set(savedMatrix);
       matrix.postTranslate(x? eventX - mStartPoint.x : 0, y? eventY - mStartPoint.y : 0);
       this.setImageMatrix(matrix);
       if(x)oldEventX = eventX;
       if(y)oldEventY = eventY;
       if(x)oldStartPointX = mStartPoint.x;
       if(y)oldStartPointY = mStartPoint.y;
   }



}

   public void zoom(MotionEvent event){
       matrix.getValues(matrixValues);
   float newDist = spacing(event);
   float bitmapWidth = matrixValues[0] * mBitmapWidth;
   float bimtapHeight = matrixValues[0] * mBitmapHeight;
   boolean in = newDist > oldDist;

   if(!in && matrixValues[0] < 1){
       return;
   }
   if(bitmapWidth > mViewWidth || bimtapHeight > mViewHeight){
       mDraggable = true;
   } else{
       mDraggable = false;
   }

   float midX = (mViewWidth / 2);
   float midY = (mViewHeight / 2);

   matrix.set(savedMatrix);
   scale = newDist / oldDist;
   matrix.postScale(scale, scale, bitmapWidth > mViewWidth ? mMiddlePoint.x : midX, bimtapHeight > mViewHeight ? mMiddlePoint.y : midY); 

   this.setImageMatrix(matrix);


   }




/** Determine the space between the first two fingers */
private float spacing(MotionEvent event) {
    float x = event.getX(0) - event.getX(1);
    float y = event.getY(0) - event.getY(1);

    return (float)Math.sqrt(x * x + y * y);
}

/** Calculate the mid point of the first two fingers */
private void midPoint(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);
}




 }

这是布局xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:background="#000" >

<mypackagename.CustomImageVIew
    android:id="@+id/imageView1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_marginBottom="5dp"
    android:layout_marginLeft="5dp"
    android:layout_marginRight="5dp"
    android:layout_marginTop="5dp"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true" 
    android:scaleType="matrix"
     />

2 个答案:

答案 0 :(得分:1)

我的猜测是你在屏幕上看到视图之前正在调用setBitmap,而它的宽度和高度仍为零。

有一些选项可以解决这个问题,但一般来说,您可以更改图像视图,以便在第一次使用宽度和高度调用setBitmap时执行onSizeChanged中的计算大于零,或第一次调用onDrawgetWidth()getHeight()都返回大于零。调用setBitmap并且视图已有宽度和高度时,请立即进行计算。

这是一个粗略的(未经测试的)插图:

@Override
public void onSizeChanged (int w, int h, int oldw, int oldh){
    super.onSizeChanged(w, h, oldw, oldh);
    mViewWidth = w;
    mViewHeight = h;
    if (w > 0 && h > 0 && mBitmapWidth > 0 && mBitmapHeight > 0) {
        centerBitmap();
    }
}

public void setBitmap(Bitmap bitmap){
    if(bitmap != null){
        setImageBitmap(bitmap);

        mBitmapWidth = bitmap.getWidth();
        mBitmapHeight = bitmap.getHeight();

        if (getWidth() > 0 && getHeight() > 0) {
            centerBitmap();
        }

    }
}

private void centerBitmap() {
    mBitmapMiddlePoint.x = (mViewWidth / 2) - (mBitmapWidth /  2);
    mBitmapMiddlePoint.y = (mViewHeight / 2) - (mBitmapHeight / 2);

    matrix.postTranslate(mBitmapMiddlePoint.x, mBitmapMiddlePoint.y);
    this.setImageMatrix(matrix);
}

答案 1 :(得分:0)

使用Framelayout而不是Relative布局并尝试..