【发布时间】:2014-03-05 04:58:07
【问题描述】:
我正在开发一个 android 应用程序 (API 19 4.4),但我遇到了 ImageViews 的一些问题。 我有一个 SurfaceView,我在其中动态添加了我想对触摸事件做出反应的 ImageView。 到目前为止,我已经设法使 ImageView 平滑地移动和缩放,但我有一个烦人的行为。
当我将图像缩小到某个限制(我会说是原始大小的一半)并尝试移动它时,图像会闪烁。 经过短暂的分析,它似乎在屏幕上围绕手指点对称地切换位置,累积距离,最后消失(所有这一切都发生得非常快(
这是我的代码
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 还是让我在视图触摸事件中使其工作?我希望能够以相同的手势缩放和旋转(并以另一个手势移动)。
感谢您的帮助,我将不胜感激!
对不起我的英语
【问题讨论】:
-
为什么在 SurfaceView 中使用 ImageView 而不是直接绘制 Bitmap?
-
如果我直接绘制位图,如何用手指移动、缩放、旋转? (我可以在我的表面视图中有十几个不同的视图,我想用手势单独管理)
-
使用矩阵(canvas.drawBitmap(Bitmap, Matrix, Paint))
-
我的意思是:如何检测我的手指在哪个位图上进行交互?
-
看看我在我的一个项目github.com/pskink/PatchworkDrawable/blob/master/…中的getLayersAt()方法中是如何做到的
标签: android view touch scale translate