package coolbuy360.control;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.widget.ImageView;
public class MyImageView1 extends ImageView {
public MyImageView1(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public MyImageView1(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
public MyImageView1(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
// ImageView img;
Matrix imgMatrix = null; // ����ͼƬ�ı任����
static final int DOUBLE_CLICK_TIME_SPACE = 300; // ˫��ʱ����
static final int DOUBLE_POINT_DISTANCE = 10; // ����Ŵ��������С���
static final int NONE = 0;
static final int DRAG = 1; // �϶�����
static final int ZOOM = 2; // �Ŵ���С����
private int mode = NONE; // ��ǰģʽ
float bigScale = 3f; // Ĭ�ϷŴ���
Boolean isBig = false; // �Ƿ��ǷŴ�״̬
long lastClickTime = 0; // ����ʱ��
float startDistance; // ��㴥���������
float endDistance; // ��㴥���������
float topHeight; // ״̬���߶Ⱥͱ������߶�
Bitmap primaryBitmap = null;
float contentW; // ��Ļ���������
float contentH; // ��Ļ�������߶�
float primaryW; // ԭͼ���
float primaryH; // ԭͼ�߶�
float scale; // �ʺ���Ļ���ű���
Boolean isMoveX = true; // �Ƿ�������X���϶�
Boolean isMoveY = true; // �Ƿ�������Y���϶�
float startX;
float startY;
float endX;
float endY;
float subX;
float subY;
float limitX1;
float limitX2;
float limitY1;
float limitY2;
ICustomMethod mCustomMethod = null;
/**
* ��ʼ��ͼƬ
*
* @param bitmap
* Ҫ��ʾ��ͼƬ
* @param contentW
* ����������
* @param contentH
* ��������߶�
* @param topHeight
* ״̬���߶Ⱥͱ������߶�֮��
*/
public void imageInit(Bitmap bitmap, int contentW, int contentH,
int topHeight, ICustomMethod iCustomMethod) {
this.primaryBitmap = bitmap;
this.contentW = contentW;
this.contentH = contentH;
this.topHeight = topHeight;
mCustomMethod = iCustomMethod;
primaryW = primaryBitmap.getWidth();
primaryH = primaryBitmap.getHeight();
float scaleX = (float) contentW / primaryW;
float scaleY = (float) contentH / primaryH;
scale = scaleX < scaleY ? scaleX : scaleY;
if (scale < 1 && 1 / scale < bigScale) {
bigScale = (float) (1 / scale + 0.5);
}
imgMatrix = new Matrix();
subX = (contentW - primaryW * scale) / 2;
subY = (contentH - primaryH * scale) / 2;
this.setImageBitmap(primaryBitmap);
this.setScaleType(ScaleType.MATRIX);
imgMatrix.postScale(scale, scale);
imgMatrix.postTranslate(subX, subY);
this.setImageMatrix(imgMatrix);
}
/**
* ���²���
*
* @param event
*/
public void mouseDown(MotionEvent event) {
mode = NONE;
startX = event.getRawX();
startY = event.getRawY();
if (event.getPointerCount() == 1) {
// ������ε��ʱ����С��һ��ֵ����Ĭ��Ϊ˫���¼�
if (event.getEventTime() - lastClickTime < DOUBLE_CLICK_TIME_SPACE) {
changeSize(startX, startY);
} else if (isBig) {
mode = DRAG;
}
}
lastClickTime = event.getEventTime();
}
/**
* �ǵ�һ���㰴�²���
*
* @param event
*/
public void mousePointDown(MotionEvent event) {
startDistance = getDistance(event);
if (startDistance > DOUBLE_POINT_DISTANCE) {
mode = ZOOM;
} else {
mode = NONE;
}
}
/**
* �ƶ�����
*
* @param event
*/
public void mouseMove(MotionEvent event) {
if ((mode == DRAG) && (isMoveX || isMoveY)) {
float[] XY = getTranslateXY(imgMatrix);
float transX = 0;
float transY = 0;
if (isMoveX) {
endX = event.getRawX();
transX = endX - startX;
if ((XY[0] + transX) <= limitX1) {
transX = limitX1 - XY[0];
}
if ((XY[0] + transX) >= limitX2) {
transX = limitX2 - XY[0];
}
}
if (isMoveY) {
endY = event.getRawY();
transY = endY - startY;
if ((XY[1] + transY) <= limitY1) {
transY = limitY1 - XY[1];
}
if ((XY[1] + transY) >= limitY2) {
transY = limitY2 - XY[1];
}
}
imgMatrix.postTranslate(transX, transY);
startX = endX;
startY = endY;
this.setImageMatrix(imgMatrix);
} else if (mode == ZOOM && event.getPointerCount() > 1) {
endDistance = getDistance(event);
float dif = endDistance - startDistance;
if (Math.abs(endDistance - startDistance) > DOUBLE_POINT_DISTANCE) {
if (isBig) {
if (dif < 0) {
changeSize(0, 0);
mode = NONE;
}
} else if (dif > 0) {
float x = event.getX(0) / 2 + event.getX(1) / 2;
float y = event.getY(0) / 2 + event.getY(1) / 2;
changeSize(x, y);
mode = NONE;
}
}
}
}
/**
* ���̧���¼�
*/
public void mouseUp() {
mode = NONE;
}
/**
* ͼƬ�Ŵ���С
*
* @param x
* �����X����
* @param y
* �����Y����
*/
private void changeSize(float x, float y) {
if (isBig) {
// ����������״̬����ԭ
imgMatrix.reset();
imgMatrix.postScale(scale, scale);
imgMatrix.postTranslate(subX, subY);
isBig = false;
} else {
imgMatrix.postScale(bigScale, bigScale); // ��ԭ�о����˷Ŵ���
float transX = -((bigScale - 1) * x);
float transY = -((bigScale - 1) * (y - topHeight)); // (bigScale-1)(y-statusBarHeight-subY)+2*subY;
float currentWidth = primaryW * scale * bigScale; // �Ŵ��ͼƬ��С
float currentHeight = primaryH * scale * bigScale;
// ���ͼƬ�Ŵ����Ļ��Χ����
if (currentHeight > contentH) {
limitY1 = -(currentHeight - contentH); // ƽ������
limitY2 = 0;
isMoveY = true; // ������Y�����϶�
float currentSubY = bigScale * subY; // ��ǰƽ�ƾ���
// ƽ�ƺ����������ϲ��пհ״���취
if (-transY < currentSubY) {
transY = -currentSubY;
}
// ƽ�ƺ����������²��пհ״���취
if (currentSubY + transY < limitY1) {
transY = -(currentHeight + currentSubY - contentH);
}
} else {
// ���ͼƬ�Ŵ��û�г�����Ļ��Χ�����������϶�
isMoveY = false;
}
if (currentWidth > contentW) {
limitX1 = -(currentWidth - contentW);
limitX2 = 0;
isMoveX = true;
float currentSubX = bigScale * subX;
if (-transX < currentSubX) {
transX = -currentSubX;
}
if (currentSubX + transX < limitX1) {
transX = -(currentWidth + currentSubX - contentW);
}
} else {
isMoveX = false;
}
imgMatrix.postTranslate(transX, transY);
isBig = true;
}
this.setImageMatrix(imgMatrix);
if (mCustomMethod != null) {
mCustomMethod.customMethod(isBig);
}
}
/**
* ��ȡ�任������X��ƫ������Y��ƫ����
*
* @param matrix
* �任����
* @return
*/
private float[] getTranslateXY(Matrix matrix) {
float[] values = new float[9];
matrix.getValues(values);
float[] floats = new float[2];
floats[0] = values[Matrix.MTRANS_X];
floats[1] = values[Matrix.MTRANS_Y];
return floats;
}
/**
* ��ȡ�����ľ���
*
* @param event
* @return
*/
private float getDistance(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
}
/**
* @author Administrator �û��Զ��巽��
*/
public interface ICustomMethod {
public void customMethod(Boolean currentStatus);
}
}