surfaceView 그림 크기 조정 드래그 기능 구현
6408 단어 android드래그SurfaceView
문제:surface를 사용하여 다중 터치 축소, 드래그 디스플레이 기능을 실현합니다.
초고 코드를 첨부해서 내일 다시 잘 정리하고,
public class MySurfaceView3 extends SurfaceView implements
SurfaceHolder.Callback, OnTouchListener {
private static final int NONE = 0;//
private static final int DRAG = 1;//
private static final int ZOOM = 2;//
private int mStatus = NONE;
private static final float MAX_ZOOM_SCALE = 4.0f;
private static final float MIN_ZOOM_SCALE = 1.0f;
private static final float FLOAT_TYPE = 1.0f;
private float mCurrentMaxScale = MAX_ZOOM_SCALE;
private float mCurrentScale = 1.0f;
private Rect mRectSrc = new Rect(); // used for render image.
private Rect mRectDes = new Rect(); // used for store size of monitor.
private int mCenterX, mCenterY;
int mSurfaceHeight, mSurfaceWidth, mImageHeight, mImageWidth;
private PointF mStartPoint = new PointF();
private float mStartDistance = 0f;
private SurfaceHolder mSurHolder = null;
private Bitmap mBitmap;
public MySurfaceView3(Context context, AttributeSet attrs) {
super(context, attrs);
mSurHolder = getHolder();
mSurHolder.addCallback(this);
this.setOnTouchListener(this);
}
private void init() {
mCurrentMaxScale = Math.max(
MIN_ZOOM_SCALE,
4 * Math.min(FLOAT_TYPE * mImageHeight / mSurfaceHeight, 1.0f
* mImageWidth / mSurfaceWidth));
mCurrentScale = MIN_ZOOM_SCALE;
mCenterX = mImageWidth / 2;
mCenterY = mImageHeight / 2;
calcRect();
}
private void adjustCenter() {
int w = mRectSrc.right - mRectSrc.left;
int h = mRectSrc.bottom - mRectSrc.top;
if (mCenterX - w / 2 < 0) {
mCenterX = w / 2;
mRectSrc.left = 0;
mRectSrc.right = w;
} else if (mCenterX + w / 2 >= mImageWidth) {
mCenterX = mImageWidth - w / 2;
mRectSrc.right = mImageWidth;
mRectSrc.left = mRectSrc.right - w;
} else {
mRectSrc.left = mCenterX - w / 2;
mRectSrc.right = mRectSrc.left + w;
}
if (mCenterY - h / 2 < 0) {
mCenterY = h / 2;
mRectSrc.top = 0;
mRectSrc.bottom = h;
} else if (mCenterY + h / 2 >= mImageHeight) {
mCenterY = mImageHeight - h / 2;
mRectSrc.bottom = mImageHeight;
mRectSrc.top = mRectSrc.bottom - h;
} else {
mRectSrc.top = mCenterY - h / 2;
mRectSrc.bottom = mRectSrc.top + h;
}
}
private void calcRect() {
int w, h;
float imageRatio, surfaceRatio;
imageRatio = FLOAT_TYPE * mImageWidth / mImageHeight;
surfaceRatio = FLOAT_TYPE * mSurfaceWidth / mSurfaceHeight;
if (imageRatio < surfaceRatio) {
h = mSurfaceHeight;
w = (int) (h * imageRatio);
} else {
w = mSurfaceWidth;
h = (int) (w / imageRatio);
}
if (mCurrentScale > MIN_ZOOM_SCALE) {
w = Math.min(mSurfaceWidth, (int) (w * mCurrentScale));
h = Math.min(mSurfaceHeight, (int) (h * mCurrentScale));
} else {
mCurrentScale = MIN_ZOOM_SCALE;
}
mRectDes.left = (mSurfaceWidth - w) / 2;
mRectDes.top = (mSurfaceHeight - h) / 2;
mRectDes.right = mRectDes.left + w;
mRectDes.bottom = mRectDes.top + h;
float curImageRatio = FLOAT_TYPE * w / h;
int h2, w2;
if (curImageRatio > imageRatio) {
h2 = (int) (mImageHeight / mCurrentScale);
w2 = (int) (h2 * curImageRatio);
} else {
w2 = (int) (mImageWidth / mCurrentScale);
h2 = (int) (w2 / curImageRatio);
}
mRectSrc.left = mCenterX - w2 / 2;
mRectSrc.top = mCenterY - h2 / 2;
mRectSrc.right = mRectSrc.left + w2;
mRectSrc.bottom = mRectSrc.top + h2;
}
public void setMaxZoom(float value) {
mCurrentMaxScale = value;
}
public void setBitmap(Bitmap b) {
if (b == null) {
return;
}
synchronized (MySurfaceView3.class) {
mBitmap = b;
if (mImageHeight != mBitmap.getHeight()
|| mImageWidth != mBitmap.getWidth()) {
mImageHeight = mBitmap.getHeight();
mImageWidth = mBitmap.getWidth();
init();
}
showBitmap();
}
}
private void showBitmap() {
synchronized (MySurfaceView3.class) {
Canvas c = getHolder().lockCanvas();
if (c != null && mBitmap != null) {
c.drawColor(Color.GRAY);
c.drawBitmap(mBitmap, mRectSrc, mRectDes, null);
getHolder().unlockCanvasAndPost(c);
}
}
}
private void dragAction(MotionEvent event) {
synchronized (MySurfaceView3.class) {
PointF currentPoint = new PointF();
currentPoint.set(event.getX(), event.getY());
int offsetX = (int) currentPoint.x - (int) mStartPoint.x;
int offsetY = (int) currentPoint.y - (int) mStartPoint.y;
mStartPoint = currentPoint;
mCenterX -= offsetX;
mCenterY -= offsetY;
adjustCenter();
showBitmap();
}
}
private void zoomAcition(MotionEvent event) {
synchronized (MySurfaceView3.class) {
float newDist = spacing(event);
float scale = newDist / mStartDistance;
mStartDistance = newDist;
mCurrentScale *= scale;
mCurrentScale = Math.max(FLOAT_TYPE,
Math.min(mCurrentScale, mCurrentMaxScale));
calcRect();
adjustCenter();
showBitmap();
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mStartPoint.set(event.getX(), event.getY());
mStatus = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
float distance = spacing(event);
if (distance > 10f) {
mStatus = ZOOM;
mStartDistance = distance;
}
break;
case MotionEvent.ACTION_MOVE:
if (mStatus == DRAG) {
dragAction(event);
} else {
if (event.getPointerCount() == 1)
return true;
zoomAcition(event);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mStatus = NONE;
break;
default:
break;
}
return true;
}
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);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
//
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
synchronized (MySurfaceView3.class) {
mRectDes.set(0, 0, width, height);
mSurfaceHeight = height;
mSurfaceWidth = width;
init();
if (mBitmap != null) {
showBitmap();
}
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.