Android的ImageView的缩放和平移问题 [英] Android ImageView Scaling and translating issue
问题描述
我开发一个Android应用程序(API 19 4.4),我遇到一些问题ImageViews。 我有一个SurfaceView,我在其中动态添加,我想应对触摸事件ImageViews。 迄今,我已成功地使ImageView的移动,顺利地扩展,但我有一个令人讨厌的行为。
I’m developing an android application (API 19 4.4) and I encounter some issue with ImageViews. I have a SurfaceView, in which I dynamically add ImageViews which I want to react to touch events. On so far, I have managed to make the ImageView move and scale smoothly but I have an annoying behavior.
当我缩小图像以一定的限度(我要说原来的一半大小),我尝试将其移动,图像闪烁。 经过短暂的分析,似乎它的对称切换其位置在屏幕上的手指点,累积距离,以及最后得到的视线(所有这种情况发生非常快(小于1秒)。 我想我失去了一些东西与触摸事件到的ImageView / SurfaceView的相对价值,但我是一个相当小白,我stucked ...
When I scale down the image to a certain limit (I would say half the original size) and I try to move it, the image flicker. After a short analysis, it seems that it’s switching its position symmetrically around the finger point on the screen, cumulating distance, and finally gets out of sight (all that happens very fast ( < 1s). I think I am missing something with the relative value of the touch event to the ImageView/SurfaceView, but I’m a quite a noob and I’m stucked…
下面是我的code
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 Down
PointF 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;
@Override
public 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);
if (!mScaleDetector.isInProgress()) {
int eid = event.getAction();
switch (eid & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_MOVE :
if(pointerId == firstPointerID) {
PointF mv = new PointF( (int)(event.getX() - DownPT.x), (int)( event.getY() - DownPT.y));
this.setX((int)(StartPT.x+mv.x));
this.setY((int)(StartPT.y+mv.y));
StartPT = new PointF( this.getX(), this.getY() );
}
break;
case MotionEvent.ACTION_DOWN : {
firstPointerID = pointerId;
DownPT.x = (int) event.getX();
DownPT.y = (int) event.getY();
StartPT = new PointF( this.getX(), this.getY() );
break;
}
case MotionEvent.ACTION_POINTER_DOWN: {
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_CANCEL: {
firstPointerID = -1;
break;
}
default :
break;
}
return true;
}
return true;
}
public boolean onScaling(ScaleGestureDetector detector) {
this.setScaleX(this.getScaleX()*detector.getScaleFactor());
this.setScaleY(this.getScaleY()*detector.getScaleFactor());
invalidate();
return true;
}
private class MySimpleOnScaleGestureListener extends SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
return onScaling(detector);
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
Log.d(TAG, "onScaleBegin");
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector arg0) {
Log.d(TAG, "onScaleEnd");
}
}
}
我也有关于转另一个问题。我应该如何实现呢? 我可以使用ScalegestureDetector在某些方面还是有我,使这部作品在视图触摸事件?我希望能够缩放和旋转在相同的手势(移动中的另一个)。
I have also another questions about rotations. How should I implement this? Could I use the ScalegestureDetector in some way or have I to make this works in the view touch event? I would like to be able to scale and rotate in the same gesture (and move in another).
感谢帮助我,我真的AP preciate!
Thank for helping me, I would really appreciate!
对不起,我的英语
推荐答案
与Android手势探测器的帮助下<一href="https://github.com/pskink/android-gesture-detectors">https://github.com/pskink/android-gesture-detectors 有两指一个工作示例移动/缩放/旋转:
with the help of android-gesture-detectors https://github.com/pskink/android-gesture-detectors there is a working example of two fingers move/scale/rotate:
class ViewPort extends View {
List<Layer> layers = new LinkedList<Layer>();
int[] ids = {R.drawable.layer0, R.drawable.layer1, R.drawable.ic_launcher};
public ViewPort(Context context) {
super(context);
Resources res = getResources();
for (int i = 0; i < ids.length; i++) {
Layer l = new Layer(context, this, BitmapFactory.decodeResource(res, ids[i]));
layers.add(l);
}
}
@Override
protected void onDraw(Canvas canvas) {
for (Layer l : layers) {
l.draw(canvas);
}
}
private Layer target;
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
target = null;
for (int i = layers.size() - 1; i >= 0; i--) {
Layer l = layers.get(i);
if (l.contains(event)) {
target = l;
layers.remove(l);
layers.add(l);
invalidate();
break;
}
}
}
if (target == null) {
return false;
}
return target.onTouchEvent(event);
}
}
class Layer {
Matrix matrix = new Matrix();
Matrix inverse = new Matrix();
RectF bounds;
View parent;
Bitmap bitmap;
MoveGestureDetector mgd;
ScaleGestureDetector sgd;
RotateGestureDetector rgd;
public Layer(Context ctx, View p, Bitmap b) {
parent = p;
bitmap = b;
bounds = new RectF(0, 0, b.getWidth(), b.getHeight());
mgd = new MoveGestureDetector(ctx, mgl);
sgd = new ScaleGestureDetector(ctx, sgl);
rgd = new RotateGestureDetector(ctx, rgl);
matrix.postTranslate(50 + (float) Math.random() * 50, 50 + (float) Math.random() * 50);
}
public boolean contains(MotionEvent event) {
matrix.invert(inverse);
float[] pts = {event.getX(), event.getY()};
inverse.mapPoints(pts);
if (!bounds.contains(pts[0], pts[1])) {
return false;
}
return Color.alpha(bitmap.getPixel((int) pts[0], (int) pts[1])) != 0;
}
public boolean onTouchEvent(MotionEvent event) {
mgd.onTouchEvent(event);
sgd.onTouchEvent(event);
rgd.onTouchEvent(event);
return true;
}
public void draw(Canvas canvas) {
canvas.drawBitmap(bitmap, matrix, null);
}
SimpleOnMoveGestureListener mgl = new SimpleOnMoveGestureListener() {
@Override
public boolean onMove(MoveGestureDetector detector) {
PointF delta = detector.getFocusDelta();
matrix.postTranslate(delta.x, delta.y);
parent.invalidate();
return true;
}
};
SimpleOnScaleGestureListener sgl = new SimpleOnScaleGestureListener() {
@Override
public boolean onScale(ScaleGestureDetector detector) {
float scale = detector.getScaleFactor();
matrix.postScale(scale, scale, detector.getFocusX(), detector.getFocusY());
parent.invalidate();
return true;
}
};
SimpleOnRotateGestureListener rgl = new SimpleOnRotateGestureListener() {
@Override
public boolean onRotate(RotateGestureDetector detector) {
matrix.postRotate(-detector.getRotationDegreesDelta(), detector.getFocusX(), detector.getFocusY());
parent.invalidate();
return true;
};
};
}
这篇关于Android的ImageView的缩放和平移问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!