Android: 줌 이동이 가능한 ImageView 만들기 (위)
1. 초기화할 때 그림을 수직으로 가운데에 표시하고 이미지 폭을 ImageView 폭으로 늘립니다.
2. 두 손가락을 사용하여 그림을 확대하고 축소하면 최대 확대 배수를 설정할 수 있다. 그림이 ImageView 너비보다 작을 때 손가락이 화면을 떠날 때 ImageView 너비로 회복된다.
3. 더블 클릭 확대 및 축소가 지원됩니다.그림이 확대되지 않은 상태일 때 두 번 클릭하면 지정한 배수로 확대되고, 그림이 확대된 상태일 때 두 번 클릭하면 확대되지 않은 상태로 회복됩니다.
4. 그림 드래그 효과.그림이 확대되지 않은 상태일 때 드래그할 수 없습니다.
5. 그림 드래그 효과.확대된 높이가 ImageView를 초과하지 않으면 수직으로 드래그할 수 없습니다.(기본적으로 ImageView 너비로 밀어내기 너비가 설정되어 있으므로 수평 방향은 판단되지 않을 수 있습니다.)
6. 이미지 드래그 효과.그림을 오른쪽으로 드래그할 때 왼쪽 가장자리가 왼쪽 경계를 초과하면 수평으로 드래그를 중지합니다.위아래 오른쪽 가장자리, 즉 드래그하면 배경이 하얗게 남지 않습니다.
먼저 원리를 말하자면 그림의 확대와 축소는 Matrix류를 사용하는 것이지만 여기서 제스처를 통해 제어하면 자연히 온터치 사건을 감청해야 하기 때문에 원리는 간단하게 말하면 온터치의 각종 사건을 감청함으로써 Matrix류를 제어하는 것이다.구체적인 제어 방법은 다음과 같습니다.
onTouch
Matrix
보조 조작
ACTION_DOWN
없음
초기 점을 기록하고 드래그 모드로 설정하고 ScaleType을 Matrix로 설정합니다.
ACTION_POINTER_DOWN
없음
배율 조정 모드로 설정
ACTION_MOVE
모드에 따라 postScale 또는 postTranslate 실행
ACTION_UP
현재 배율 수준에 따라 Matrix 재설정 여부 결정
더블 클릭
postScale
ACTION_CANCEL
UP
지금부터 기능점에 따라 코드 설명을 일일이 열거합니다.
먼저 ImageView를 사용자 정의하고 Matrix와 관련하여 Matrix ImageView라는 이름을 지정합니다.java, ImageView에서 상속.java
public class MatrixImageView extends ImageView{
private final static String TAG="MatrixImageView";
private GestureDetector mGestureDetector;
/** Matrix, */
private Matrix mMatrix=new Matrix();
/** */
private float mImageWidth;
/** */
private float mImageHeight;
public MatrixImageView(Context context, AttributeSet attrs) {
super(context, attrs);
MatrixTouchListener mListener=new MatrixTouchListener();
setOnTouchListener(mListener);
mGestureDetector=new GestureDetector(getContext(), new GestureListener(mListener));
// balck
setBackgroundColor(Color.BLACK);
// FIT_CENTER, / View ,
setScaleType(ScaleType.FIT_CENTER);
}
더블 클릭 축소 효과를 사용했기 때문에 제스처 클래스인 Gesture Detector를 인용했습니다. Gesture Listener는 Simple On Gesture Listener와 제스처 감청 클래스를 계승하는 것입니다.Matrix Touch Listener 계승과 onTouch Listner는 Touch 이벤트 감청의 주체이다.구조 함수 마지막 문장인 setScaleType(ScaleType.FIT CENTER)는 기능 1을 만족시키는 요점이다.
이어서 setImageBitmap 방법을 다시 쓰십시오.
@Override
public void setImageBitmap(Bitmap bm) {
// TODO Auto-generated method stub
super.setImageBitmap(bm);
// ,
mMatrix.set(getImageMatrix());
float[] values=new float[9];
mMatrix.getValues(values);
//
mImageWidth=getWidth()/values[Matrix.MSCALE_X];
mImageHeight=(getHeight()-values[Matrix.MTRANS_Y]*2)/values[Matrix.MSCALE_Y];
}
다음과 같은 몇 가지 중요한 변수를 초기화합니다.
mMatrix: 그림의 원시적인 Matrix를 템플릿으로 기록하고 그 후의 변화는 모두 이 Matrix의 기초 위에서 진행된다
mImageWidth: 그림의 실제 너비입니다. 이 너비는 그림이 ImageView에 있는 실제 너비입니다. 화면표시도 파일 너비도 아닙니다.그림을 ImageView에 넣을 때, ImageView의 넓이에 따라 변환되며, 변환 결과는 Matrix에 기록됩니다.표시 너비와 Matrix를 기준으로 실제 너비를 계산했습니다.
mImageHeight: 너비가 같습니다.
세 가지 너비의 차이
표시 폭: ImageView의 그림(Bitmap, Drawable)이 ImageView에 표시되는 높이는 Matrix를 통해 계산된 폭입니다.그림을 확대할 때 이 너비는 ImageView 너비를 초과할 수 있습니다.
실제 너비: Matrix가 계산하기 전의 ImageView 그림의 너비입니다.ImageView 너비가 390이면 그림 X축의 축소 레벨은 0.5이고 ImageView가 가득 찬 X축의 그림의 실제 너비는 780이다.이 너비는 ImageView의 ScaleType과 연관됩니다.
파일 너비: 파일 X축 해상도가 실제 너비와 같을 필요는 없습니다.
sitImageView에서 설정을 하는 이유는 ImageView가 그림을 바꿀 때마다 이 변수가 바뀌기 때문에 현재 그림과 관련된 변수만 필요합니다.layout에서 코드가 아닌 그림을 설정하려면 상기 코드를 구조 함수로 이동하십시오.
다음은 주요 onTouch 이벤트입니다.
public class MatrixTouchListener implements OnTouchListener{
/** */
private static final int MODE_DRAG = 1;
/** */
private static final int MODE_ZOOM = 2;
/** Matrix */
private static final int MODE_UNABLE=3;
/** */
float mMaxScale=6;
/** */
float mDobleClickScale=2;
private int mMode = 0;//
/** */
private float mStartDis;
/** Matrix*/
private Matrix mCurrentMatrix = new Matrix();
/** */
private PointF startPoint = new PointF();
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
//
mMode=MODE_DRAG;
startPoint.set(event.getX(), event.getY());
// isMatrixEnable();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
reSetMatrix();
break;
case MotionEvent.ACTION_MOVE:
if (mMode == MODE_ZOOM) {
setZoomMatrix(event);
}else if (mMode==MODE_DRAG) {
setDragMatrix(event);
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
if(mMode==MODE_UNABLE) return true;
mMode=MODE_ZOOM;
mStartDis = distance(event);
break;
default:
break;
}
return mGestureDetector.onTouchEvent(event);
}
/**
*
* @param event
* @return
*/
private float distance(MotionEvent event) {
float dx = event.getX(1) - event.getX(0);
float dy = event.getY(1) - event.getY(0);
/** */
return (float) Math.sqrt(dx * dx + dy * dy);
}
먼저 ACTION에서DOWN 및 ACTIONPOINTER_DOWN에서는 주로 현재 이벤트 모드를 확인합니다.한 점을 누르면 Down 이벤트가 발생하고 두 번째 점을 누르면 ActionPointer_Down 이벤트, 여기에서 우리는 한 점을 누르면 드래그 이벤트로 표시하고, 두 점을 누르면 축소 이벤트로 표시합니다.이벤트 배율 조정 방법 setZoomMatrix(event) 추적하기
/**
* Matrix
* @param event
*/
private void setZoomMatrix(MotionEvent event) {
//
if(event.getPointerCount()<2) return;
float endDis = distance(event);//
if (endDis > 10f) { // 10
float scale = endDis / mStartDis;//
mStartDis=endDis;//
mCurrentMatrix.set(getImageMatrix());// Matrix
float[] values=new float[9];
mCurrentMatrix.getValues(values);
scale = checkMaxScale(scale, values);
setImageMatrix(mCurrentMatrix);
}
}
우선 두 개의 포인트를 눌렀는지 아닌지를 판단합니다. 직접 되돌아오지 않았다면.다음에distance 방법을 사용하여 두 점 사이의 거리를 계산해 낸다.이전에 Action에서Pointer_Down에서는 이미 초기 거리를 계산했는데 여기서 계산된 것은 이동한 두 점의 거리이다.이 두 거리를 통해 우리는 이번 이동의 축소 배수를 얻어낼 수 있지만, 이것은 아직 끝나지 않았다. 우리는 이 축소 배수가 경계를 넘었는지 검증해야 한다.
/**
* scale,
* @param scale
* @param values
* @return
*/
private float checkMaxScale(float scale, float[] values) {
if(scale*values[Matrix.MSCALE_X]>mMaxScale)
scale=mMaxScale/values[Matrix.MSCALE_X];
mCurrentMatrix.postScale(scale, scale,getWidth()/2,getHeight()/2);
return scale;
}
Matrix 행렬에 저장된 그룹을 가져왔습니다. 이 그룹에서values[matrix.MSCALE X] (사실상 그룹의 0번째) 는 X축의 축소 단계를 대표합니다. 그림의 현재 축소 단계를 판단하고, 방금 얻은 scale를 곱해서 경계를 넘어갈지 여부를 판단합니다. 그러면 경계값으로 제어합니다.그런 다음 ImageView의 중심점을 원점으로 하여 현재 Matrix의 배수를 기준으로 배율을 지정합니다.
Move 이벤트에서 배율을 조정할 때 우리는 최대치를 초과하는 배율만 막고 UP 이벤트에서는 원시 배율 조정값보다 작은 배율을 초기화합니다.메서드 reSetMatrix는 다음과 같습니다.
/**
* Matrix
*/
private void reSetMatrix() {
if(checkRest()){
mCurrentMatrix.set(mMatrix);
setImageMatrix(mCurrentMatrix);
}
}
/**
*
* @return ,
*/
private boolean checkRest() {
// TODO Auto-generated method stub
float[] values=new float[9];
getImageMatrix().getValues(values);
// X
float scale=values[Matrix.MSCALE_X];
// X ,
mMatrix.getValues(values);
return scale<values[Matrix.MSCALE_X];
}
먼저 현재 X축 배율 레벨을 가져옵니다(기본적으로 ImageView 너비에서 ImageView 너비로 배율 레벨은 X축 기준). 그리고 템플릿 Matrix를 통해 원래 X축 배율 레벨을 받아서 현재 배율 레벨이 템플릿 배율 레벨보다 작은지 판단하고 작으면 템플릿 배율 레벨로 재설정합니다.
다음은 두 번 클릭하여 이미지 효과를 확대하고 축소하는 기능입니다. 이 기능은 제스처 인터페이스GestureListener에서 완성되며 주요 코드는 다음과 같습니다.
private class GestureListener extends SimpleOnGestureListener{
private final MatrixTouchListener listener;
public GestureListener(MatrixTouchListener listener) {
this.listener=listener;
}
@Override
public boolean onDown(MotionEvent e) {
// Down
return true;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
//
listener.onDoubleClick();
return true;
}
/**
*
*/
public void onDoubleClick(){
float scale=isZoomChanged()?1:mDobleClickScale;
mCurrentMatrix.set(mMatrix);// Matrix
mCurrentMatrix.postScale(scale, scale,getWidth()/2,getHeight()/2);
setImageMatrix(mCurrentMatrix);
}
/**
*
* @return true ,false
*/
private boolean isZoomChanged() {
float[] values=new float[9];
getImageMatrix().getValues(values);
// X
float scale=values[Matrix.MSCALE_X];
// X ,
mMatrix.getValues(values);
return scale!=values[Matrix.MSCALE_X];
}
구조 함수에서 onTouchListner를 전달합니다.여기에 두 가지 방법만 다시 씁니다: Down과 onDouble Tap. Down 이벤트에서true를 되돌려야 onDouble Tap이 정상적으로 터치됩니다.
onDoubleClick 이벤트에서 먼저 isZoomChanged 방법을 통해 현재 크기 조정 레벨이 템플릿Matrix의 크기 조정 레벨인지 판단합니다. 그러면 크기 조정 배수를 2배로 설정하고, 그렇지 않으면 1배로 설정합니다.템플릿 Matrix를 로드하고 여기서 배율을 조정합니다.
마지막으로 그림 드래그 효과 setDragMatrix ()
public void setDragMatrix(MotionEvent event) {
if(isZoomChanged()){
float dx = event.getX() - startPoint.x; // x
float dy = event.getY() - startPoint.y; // x
// , 10f
if(Math.sqrt(dx*dx+dy*dy)>10f){
startPoint.set(event.getX(), event.getY());
//
mCurrentMatrix.set(getImageMatrix());
float[] values=new float[9];
mCurrentMatrix.getValues(values);
dx=checkDxBound(values,dx);
dy=checkDyBound(values,dy);
mCurrentMatrix.postTranslate(dx, dy);
setImageMatrix(mCurrentMatrix);
}
}
}
먼저 isZoomChanged 방법으로 축소 여부를 판단하고 축소하지 않으면 드래그할 수 없습니다. (이 경우 그림의 전체 모습을 볼 수 있고 드래그할 필요가 없습니다.)이어서 현재 좌표와 눌렀을 때 기록된 startPoint 좌표를 가지고 계산하여 드래그하는 거리를 계산합니다.주의해야 할 것은 드래그 거리에 대한 판단이 필요합니다. 10f보다 작을 때 드래그를 하지 않으면 더블 클릭 이벤트와 충돌합니다. (더블 클릭 이벤트 전에도 무브 이벤트를 촉발합니다. 둘을 함께 실행하면 더블 클릭의 축소가 정상적으로 작동하지 않습니다.)드래그를 시작한 후 startPoint의 좌표를 초기화한 다음 현재 이동의 위치 이동량이 합법적인지 확인하기 시작합니다.
/**
* , dx, ImageView
* @param values
* @param dx
* @return
*/
private float checkDxBound(float[] values,float dx) {
float width=getWidth();
if(mImageWidth*values[Matrix.MSCALE_X]<width)
return 0;
if(values[Matrix.MTRANS_X]+dx>0)
dx=-values[Matrix.MTRANS_X];
else if(values[Matrix.MTRANS_X]+dx<-(mImageWidth*values[Matrix.MSCALE_X]-width))
dx=-(mImageWidth*values[Matrix.MSCALE_X]-width)-values[Matrix.MTRANS_X];
return dx;
}
/**
* , dy, ImageView
* @param values
* @param dy
* @return
*/
private float checkDyBound(float[] values, float dy) {
float height=getHeight();
if(mImageHeight*values[Matrix.MSCALE_Y]<height)
return 0;
if(values[Matrix.MTRANS_Y]+dy>0)
dy=-values[Matrix.MTRANS_Y];
else if(values[Matrix.MTRANS_Y]+dy<-(mImageHeight*values[Matrix.MSCALE_Y]-height))
dy=-(mImageHeight*values[Matrix.MSCALE_Y]-height)-values[Matrix.MTRANS_Y];
return dy;
}
Y축의 경우 먼저 ImageView 높이를 가져오고sitImageBitmap 방법에서 얻은 그림의 실제 높이와 현재 Y축의 축소 단계를 통해 현재 Y축의 표시 높이를 계산합니다.디스플레이 높이가 ImageView 높이보다 작으면 현재 표시된 그림이 ImageView 높이보다 높지 않다는 것을 나타낸다. Y축에서 이동할 필요가 없이 전체 모습을 볼 수 있고 Y축의 위치 이동량은 0으로 되돌아간다.
만약 표시 높이가 ImageView 높이를 초과한다면 그림이 현재 Y축에 있는 위치 이동량(values[matrix.MTRANS Y] 값)을 가져오고 계산된 위치 이동량을 더하면 0보다 큰지 여부입니다. 0보다 크면 그림의 가장자리가 ImageView 위쪽 가장자리를 벗어나므로 위치 이동량을 다시 계산해야 합니다.상기 조건이 성립되지 않으면 현재 위치 이동량에 계산된 위치 이동량을 더하면 그림 표시 높이-화면 높이보다 작은지 판단하고, 그림 아래 가장자리가 ImageView 아래 가장자리를 벗어난다는 뜻보다 작으면 다시 계산해야 한다.마지막으로 계산된 Y축 오프셋을 반환합니다.X축 동리.마지막으로 검증된 X, Y축 오프셋을 사용하여 현재 그림Matrix의 기초 위에서 오프셋합니다.
마지막으로 전체 코드를 붙이고 데모를 붙이면 제 카메라 데모에서 볼 수 있습니다. 이 기능은 앨범 기능의 일부분입니다.
package com.linj.album.view;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
/**
* @ClassName: MatrixImageView
* @Description: 、 、 ImageView
* @author LinJ
* @date 2015-1-7 11:15:07
*
*/
public class MatrixImageView extends ImageView{
private final static String TAG="MatrixImageView";
private GestureDetector mGestureDetector;
/** Matrix, */
private Matrix mMatrix=new Matrix();
/** */
private float mImageWidth;
/** */
private float mImageHeight;
public MatrixImageView(Context context, AttributeSet attrs) {
super(context, attrs);
MatrixTouchListener mListener=new MatrixTouchListener();
setOnTouchListener(mListener);
mGestureDetector=new GestureDetector(getContext(), new GestureListener(mListener));
// balck
setBackgroundColor(Color.BLACK);
// FIT_CENTER, / View ,
setScaleType(ScaleType.FIT_CENTER);
}
@Override
public void setImageBitmap(Bitmap bm) {
// TODO Auto-generated method stub
super.setImageBitmap(bm);
// ,
mMatrix.set(getImageMatrix());
float[] values=new float[9];
mMatrix.getValues(values);
//
mImageWidth=getWidth()/values[Matrix.MSCALE_X];
mImageHeight=(getHeight()-values[Matrix.MTRANS_Y]*2)/values[Matrix.MSCALE_Y];
}
public class MatrixTouchListener implements OnTouchListener{
/** */
private static final int MODE_DRAG = 1;
/** */
private static final int MODE_ZOOM = 2;
/** Matrix */
private static final int MODE_UNABLE=3;
/** */
float mMaxScale=6;
/** */
float mDobleClickScale=2;
private int mMode = 0;//
/** */
private float mStartDis;
/** Matrix*/
private Matrix mCurrentMatrix = new Matrix();
/** */
private PointF startPoint = new PointF();
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
//
mMode=MODE_DRAG;
startPoint.set(event.getX(), event.getY());
isMatrixEnable();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
reSetMatrix();
break;
case MotionEvent.ACTION_MOVE:
if (mMode == MODE_ZOOM) {
setZoomMatrix(event);
}else if (mMode==MODE_DRAG) {
setDragMatrix(event);
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
if(mMode==MODE_UNABLE) return true;
mMode=MODE_ZOOM;
mStartDis = distance(event);
break;
default:
break;
}
return mGestureDetector.onTouchEvent(event);
}
public void setDragMatrix(MotionEvent event) {
if(isZoomChanged()){
float dx = event.getX() - startPoint.x; // x
float dy = event.getY() - startPoint.y; // x
// , 10f
if(Math.sqrt(dx*dx+dy*dy)>10f){
startPoint.set(event.getX(), event.getY());
//
mCurrentMatrix.set(getImageMatrix());
float[] values=new float[9];
mCurrentMatrix.getValues(values);
dx=checkDxBound(values,dx);
dy=checkDyBound(values,dy);
mCurrentMatrix.postTranslate(dx, dy);
setImageMatrix(mCurrentMatrix);
}
}
}
/**
*
* @return true ,false
*/
private boolean isZoomChanged() {
float[] values=new float[9];
getImageMatrix().getValues(values);
// X
float scale=values[Matrix.MSCALE_X];
// X ,
mMatrix.getValues(values);
return scale!=values[Matrix.MSCALE_X];
}
/**
* , dy, ImageView
* @param values
* @param dy
* @return
*/
private float checkDyBound(float[] values, float dy) {
float height=getHeight();
if(mImageHeight*values[Matrix.MSCALE_Y]<height)
return 0;
if(values[Matrix.MTRANS_Y]+dy>0)
dy=-values[Matrix.MTRANS_Y];
else if(values[Matrix.MTRANS_Y]+dy<-(mImageHeight*values[Matrix.MSCALE_Y]-height))
dy=-(mImageHeight*values[Matrix.MSCALE_Y]-height)-values[Matrix.MTRANS_Y];
return dy;
}
/**
* , dx, ImageView
* @param values
* @param dx
* @return
*/
private float checkDxBound(float[] values,float dx) {
float width=getWidth();
if(mImageWidth*values[Matrix.MSCALE_X]<width)
return 0;
if(values[Matrix.MTRANS_X]+dx>0)
dx=-values[Matrix.MTRANS_X];
else if(values[Matrix.MTRANS_X]+dx<-(mImageWidth*values[Matrix.MSCALE_X]-width))
dx=-(mImageWidth*values[Matrix.MSCALE_X]-width)-values[Matrix.MTRANS_X];
return dx;
}
/**
* Matrix
* @param event
*/
private void setZoomMatrix(MotionEvent event) {
//
if(event.getPointerCount()<2) return;
float endDis = distance(event);//
if (endDis > 10f) { // 10
float scale = endDis / mStartDis;//
mStartDis=endDis;//
mCurrentMatrix.set(getImageMatrix());// Matrix
float[] values=new float[9];
mCurrentMatrix.getValues(values);
scale = checkMaxScale(scale, values);
setImageMatrix(mCurrentMatrix);
}
}
/**
* scale,
* @param scale
* @param values
* @return
*/
private float checkMaxScale(float scale, float[] values) {
if(scale*values[Matrix.MSCALE_X]>mMaxScale)
scale=mMaxScale/values[Matrix.MSCALE_X];
mCurrentMatrix.postScale(scale, scale,getWidth()/2,getHeight()/2);
return scale;
}
/**
* Matrix
*/
private void reSetMatrix() {
if(checkRest()){
mCurrentMatrix.set(mMatrix);
setImageMatrix(mCurrentMatrix);
}
}
/**
*
* @return ,
*/
private boolean checkRest() {
// TODO Auto-generated method stub
float[] values=new float[9];
getImageMatrix().getValues(values);
// X
float scale=values[Matrix.MSCALE_X];
// X ,
mMatrix.getValues(values);
return scale<values[Matrix.MSCALE_X];
}
/**
* Matrix
*/
private void isMatrixEnable() {
// ,
if(getScaleType()!=ScaleType.CENTER){
setScaleType(ScaleType.MATRIX);
}else {
mMode=MODE_UNABLE;//
}
}
/**
*
* @param event
* @return
*/
private float distance(MotionEvent event) {
float dx = event.getX(1) - event.getX(0);
float dy = event.getY(1) - event.getY(0);
/** */
return (float) Math.sqrt(dx * dx + dy * dy);
}
/**
*
*/
public void onDoubleClick(){
float scale=isZoomChanged()?1:mDobleClickScale;
mCurrentMatrix.set(mMatrix);// Matrix
mCurrentMatrix.postScale(scale, scale,getWidth()/2,getHeight()/2);
setImageMatrix(mCurrentMatrix);
}
}
private class GestureListener extends SimpleOnGestureListener{
private final MatrixTouchListener listener;
public GestureListener(MatrixTouchListener listener) {
this.listener=listener;
}
@Override
public boolean onDown(MotionEvent e) {
// Down
return true;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
//
listener.onDoubleClick();
return true;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
// TODO Auto-generated method stub
return super.onSingleTapUp(e);
}
@Override
public void onLongPress(MotionEvent e) {
// TODO Auto-generated method stub
super.onLongPress(e);
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
return super.onScroll(e1, e2, distanceX, distanceY);
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
// TODO Auto-generated method stub
return super.onFling(e1, e2, velocityX, velocityY);
}
@Override
public void onShowPress(MotionEvent e) {
// TODO Auto-generated method stub
super.onShowPress(e);
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
// TODO Auto-generated method stub
return super.onDoubleTapEvent(e);
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
// TODO Auto-generated method stub
return super.onSingleTapConfirmed(e);
}
}
}
참고: ImageView가 일반적인 ViewPager와 같은 다른 ViewGroup에 있는 경우 Move 이벤트와 ViewGroup 이벤트가 충돌합니다.스크린을 그어 ViewPager의 Item 전환을 진행할 때 Viewpager는 onInterceptTouchEvent 방법을 통해 차단하고 ImageView에 Cancel 이벤트를 되돌려줍니다. 이 경우 ViewGroup의 onInterceptTouchEvent 방법을 다시 써야 합니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.