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 回答
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
提交
取消
