안드로이드 개발 질문/답변
(글 수 45,052)
FrameLayout 안에
ImageView 가 있고 안에
Bitmap 이 하나 있습니다.
터치 드래그 이동(+핀투 확대) 소스를 구했고, 수정을 하려고 하는데 좀 어렵습니다.
이 소스는 그냥 드래그 하면 이동이 안되고, 비트맵을 확대를 해서 이미지뷰 이상으로 커지면 그 이미지 뷰 내에서 이동이 가능합니다.
저는 일정한 이미지 뷰 내에서 (또는 밖으로 어느정도 나가도 됨) 이미지를 이동하게 하려고 합니다. (또는 이미지뷰 자체를 프레임레이아웃내에서 이동하게 하는게 편하겠죠)
하지만 왜 이미지뷰 크기보다 이미지크기가 작을때는 드래그를 해도 이동이 안되는지 ㅠㅠ
도무지 소스를 봐도 알아낼수가 없습니다.
혹시 궁금하신분들 있으실까봐 소스 씁니다,
다른 저도 다른 곳에서 퍼온 소스 입니다.
출저: http://blog.flysky.kr/?mid=blog&document_srl=4547416
확장 컴포넌트 엔터버그가 절 힘들게 합니다. ㅠㅠ
public class ImgViewTouch extends ImageView implements OnTouchListener{
// 디버깅 정보
private static final String TAG = "ViewTouchImage";
private static final boolean D = false;
private Matrix matrix = new Matrix();
private Matrix savedMatrix = new Matrix();
private Matrix savedMatrix2 = new Matrix();
private static final int NONE = 0;
private static final int DRAG = 1;
private static final int ZOOM = 2;
private int mode = NONE;
private PointF start = new PointF();
private PointF mid = new PointF();
private float oldDist = 1f;
private static final int WIDTH = 0;
private static final int HEIGHT = 1;
private boolean isInit = false;
public ImgViewTouch(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setOnTouchListener(this);
setScaleType(ScaleType.MATRIX);
}
public ImgViewTouch(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ImgViewTouch(Context context) {
this(context, null);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (D) Log.i(TAG, "onLayout");
super.onLayout(changed, left, top, right, bottom);
if (isInit == false){
init();
isInit = true;
}
}
@Override
public void setImageBitmap(Bitmap bm) {
if (D) Log.i(TAG, "setImageBitmap");
super.setImageBitmap(bm);
isInit = false;
init();
}
@Override
public void setImageDrawable(Drawable drawable) {
if (D) Log.i(TAG, "setImageDrawable");
super.setImageDrawable(drawable);
isInit = false;
init();
}
@Override
public void setImageResource(int resId) {
if (D) Log.i(TAG, "setImageResource");
super.setImageResource(resId);
isInit = false;
init();
}
protected void init() {
matrixTurning(matrix, this);
setImageMatrix(matrix);
setImagePit();
}
/**
* 이미지 핏
*/
public void setImagePit(){
// 매트릭스 값
float[] value = new float[9];
this.matrix.getValues(value);
// 뷰 크기
int width = this.getWidth();
int height = this.getHeight();
// 이미지 크기
Drawable d = this.getDrawable();
if (d == null) return;
int imageWidth = d.getIntrinsicWidth();
int imageHeight = d.getIntrinsicHeight();
int scaleWidth = (int) (imageWidth * value[0]);
int scaleHeight = (int) (imageHeight * value[4]);
// 이미지가 바깥으로 나가지 않도록.
value[2] = 0;
value[5] = 0;
if (imageWidth > width || imageHeight > height){
int target = WIDTH;
if (imageWidth < imageHeight) target = HEIGHT;
if (target == WIDTH) value[0] = value[4] = (float)width / imageWidth;
if (target == HEIGHT) value[0] = value[4] = (float)height / imageHeight;
scaleWidth = (int) (imageWidth * value[0]);
scaleHeight = (int) (imageHeight * value[4]);
if (scaleWidth > width) value[0] = value[4] = (float)width / imageWidth;
if (scaleHeight > height) value[0] = value[4] = (float)height / imageHeight;
}
// 그리고 가운데 위치하도록 한다.
scaleWidth = (int) (imageWidth * value[0]);
scaleHeight = (int) (imageHeight * value[4]);
if (scaleWidth < width){
value[2] = (float) width / 2 - (float)scaleWidth / 2;
}
if (scaleHeight < height){
value[5] = (float) height / 2 - (float)scaleHeight / 2;
}
matrix.setValues(value);
setImageMatrix(matrix);
}
//손가락 터치 이벤트처리
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x, event.getY() - start.y);
}
else if (mode == ZOOM) {
float newDist = spacing(event);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
break;
}
// 매트릭스 값 튜닝.
matrixTurning(matrix, view);
view.setImageMatrix(matrix);
return true;
}
private float spacing(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);
}
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);
}
private void matrixTurning(Matrix matrix, ImageView view){
// 매트릭스 값
float[] value = new float[9];
matrix.getValues(value);
float[] savedValue = new float[9];
savedMatrix2.getValues(savedValue);
// 뷰 크기
int width = view.getWidth();
int height = view.getHeight();
// 이미지 크기
Drawable d = view.getDrawable();
if (d == null) return;
int imageWidth = d.getIntrinsicWidth();
int imageHeight = d.getIntrinsicHeight();
int scaleWidth = (int) (imageWidth * value[0]);
int scaleHeight = (int) (imageHeight * value[4]);
// 이미지가 바깥으로 나가지 않도록.
if (value[2] < width - scaleWidth) value[2] = width - scaleWidth;
if (value[5] < height - scaleHeight) value[5] = height - scaleHeight;
if (value[2] > 0) value[2] = 0;
if (value[5] > 0) value[5] = 0;
// 10배 이상 확대 하지 않도록
if (value[0] > 10 || value[4] > 10){
value[0] = savedValue[0];
value[4] = savedValue[4];
value[2] = savedValue[2];
value[5] = savedValue[5];
}
// 화면보다 작게 축소 하지 않도록
if (imageWidth > width || imageHeight > height){
if (scaleWidth < width && scaleHeight < height){
int target = WIDTH;
if (imageWidth < imageHeight) target = HEIGHT;
if (target == WIDTH) value[0] = value[4] = (float)width / imageWidth;
if (target == HEIGHT) value[0] = value[4] = (float)height / imageHeight;
scaleWidth = (int) (imageWidth * value[0]);
scaleHeight = (int) (imageHeight * value[4]);
if (scaleWidth > width) value[0] = value[4] = (float)width / imageWidth;
if (scaleHeight > height) value[0] = value[4] = (float)height / imageHeight;
}
}
// 원래부터 작은 얘들은 본래 크기보다 작게 하지 않도록
else{
if (value[0] < 1) value[0] = 1;
if (value[4] < 1) value[4] = 1;
}
// 그리고 가운데 위치하도록 한다.
scaleWidth = (int) (imageWidth * value[0]);
scaleHeight = (int) (imageHeight * value[4]);
if (scaleWidth < width){
value[2] = (float) width / 2 - (float)scaleWidth / 2;
}
if (scaleHeight < height){
value[5] = (float) height / 2 - (float)scaleHeight / 2;
}
matrix.setValues(value);
savedMatrix2.set(matrix);
}
}