Android图像视图缩放和翻译问题我正在开发一个Android应用程序(API 194.4),我遇到了ImageViews的一些问题。我有一个SurfaceView,在其中我动态地添加了ImageViews,我想对触摸事件做出反应。到目前为止,我已经成功地使ImageView移动和缩放顺利,但我有一个恼人的行为。当我缩小图像到一定的限制(我可以说是原始大小的一半),我试图移动它,图像闪烁。经过一个简短的分析,它似乎是对称地在屏幕上的手指周围切换它的位置,累积距离,最后离开视线(这一切发生得非常快(<1s)。我想我错过了一些东西,与ImageView/SurfaceView相比,触摸事件的相对价值,但我是个菜鸟,而且我被塞进了…这是我的密码public class MyImageView extends ImageView {private ScaleGestureDetector mScaleDetector ;
private static final int MAX_SIZE = 1024;private static final String TAG = "MyImageView";
PointF DownPT = new PointF(); // Record Mouse Position When Pressed DownPointF StartPT = new PointF();
// Record Start Position of 'img'public MyImageView(Context context) {
super(context);
mScaleDetector = new ScaleGestureDetector(context,new MySimpleOnScaleGestureListener());
setBackgroundColor(Color.RED);
setScaleType(ScaleType.MATRIX);
setAdjustViewBounds(true);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(-MAX_SIZE, -MAX_SIZE, -MAX_SIZE, -MAX_SIZE);
this.setLayoutParams(lp);
this.setX(MAX_SIZE);
this.setY(MAX_SIZE);}int firstPointerID;boolean inScaling=false;@Overridepublic boolean onTouchEvent(MotionEvent event) {
// get pointer index from the event object
int pointerIndex = event.getActionIndex();
// get pointer ID
int pointerId = event.getPointerId(pointerIndex);
//First send event to scale detector to find out, if it's a scale
boolean res = mScaleDetector.onTouchEvent(event);}我还有另外一个关于轮调的问题。我应该如何实现这一点?我是否可以某种方式使用ScalegestureDetector,或者让我让它在视图触摸事件中工作呢?我希望能够以相同的姿态缩放和旋转(并在另一个手势中移动)。谢谢你的帮助,我真的很感激!
3 回答
![?](http://img1.sycdn.imooc.com/54584ed2000152a202200220-100-100.jpg)
MMMHUHU
TA贡献1834条经验 获得超8个赞
public class MultiTouchImageView extends ImageView implements OnTouchListener{float[] lastEvent = null;float d = 0f;float newRot = 0f; public static String fileNAME;public static int framePos = 0;//private ImageView view;private boolean isZoomAndRotate; private boolean isOutSide;// We can be in one of these 3 statesprivate 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();float oldDist = 1f;public MultiTouchImageView(Context context) { super(context);}public MultiTouchImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle);}public MultiTouchImageView(Context context, AttributeSet attrs) { super(context, attrs);}@SuppressWarnings("deprecation")@Overridepublic boolean onTouch(View v, MotionEvent event) { //view = (ImageView) v; bringToFront(); // Handle touch events here... switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: //savedMatrix.set(matrix); start.set(event.getX(), event.getY()); mode = DRAG; lastEvent = null; break; case MotionEvent.ACTION_POINTER_DOWN: oldDist = spacing(event); if (oldDist > 10f) { midPoint(mid, event); mode = ZOOM; } lastEvent = new float[4]; lastEvent[0] = event.getX(0); lastEvent[1] = event.getX(1); lastEvent[2] = event.getY(0); lastEvent[3] = event.getY(1); d = rotation(event); break; case MotionEvent.ACTION_UP: isZoomAndRotate = false; case MotionEvent.ACTION_OUTSIDE: isOutSide = true; mode = NONE; lastEvent = null; case MotionEvent.ACTION_POINTER_UP: mode = NONE; lastEvent = null; break; case MotionEvent.ACTION_MOVE: if(!isOutSide){ if (mode == DRAG && !isZoomAndRotate) { isZoomAndRotate = false; setTranslationX((event.getX() - start.x) + getTranslationX()); setTranslationY((event.getY() - start.y) + getTranslationY()); } else if (mode == ZOOM && event.getPointerCount() == 2) { isZoomAndRotate = true; boolean isZoom = false; if(!isRotate(event)){ float newDist = spacing(event); if (newDist > 10f) { float scale = newDist / oldDist * getScaleX(); setScaleX(scale); setScaleY(scale); isZoom = true; } } else if(!isZoom){ newRot = rotation(event); setRotation((float)(getRotation() + (newRot - d))); } } } break; } new GestureDetector(new MyGestureDectore()); Constants.currentSticker = this; return true;}private class MyGestureDectore extends GestureDetector.SimpleOnGestureListener{ @Override public boolean onDoubleTap(MotionEvent e) { bringToFront(); return false; } @Override public boolean onDoubleTapEvent(MotionEvent e) { return false; }}private float rotation(MotionEvent event) { double delta_x = (event.getX(0) - event.getX(1)); double delta_y = (event.getY(0) - event.getY(1)); double radians = Math.atan2(delta_y, delta_x); return (float) Math.toDegrees(radians);}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 boolean isRotate(MotionEvent event){ int dx1 = (int) (event.getX(0) - lastEvent[0]); int dy1 = (int) (event.getY(0) - lastEvent[2]); int dx2 = (int) (event.getX(1) - lastEvent[1]); int dy2 = (int) (event.getY(1) - lastEvent[3]); Log.d("dx1 ", ""+ dx1); Log.d("dx2 ", "" + dx2); Log.d("dy1 ", "" + dy1); Log.d("dy2 ", "" + dy2); //pointer 1 if(Math.abs(dx1) > Math.abs(dy1) && Math.abs(dx2) > Math.abs(dy2)) { if(dx1 >= 2.0 && dx2 <= -2.0){ Log.d("first pointer ", "right"); return true; } else if(dx1 <= -2.0 && dx2 >= 2.0){ Log.d("first pointer ", "left"); return true; } } else { if(dy1 >= 2.0 && dy2 <= -2.0){ Log.d("seccond pointer ", "top"); return true; } else if(dy1 <= -2.0 && dy2 >= 2.0){ Log.d("second pointer ", "bottom"); return true; } } return false;}}
添加回答
举报
0/150
提交
取消