java - 如何在 Android 的屏幕上拖动对象?我不知道如何在 Android 文档网站上集成示例 onTouchEvent() 代码
问题描述
我只是想在屏幕上触摸并拖动/移动一个对象。
我知道那里有很多给定的代码,使用表面支架和图像视图矩阵。但是这些代码没有很好地标记,我不知道发生了什么。我只想将它们复制并粘贴到我自己的代码中。
我知道 Android Dev 网站上有这个文档可以教你如何拖动和缩放。但是对于拖动,它仅给出了 onTouchEvent() 的示例,但我不知道如何将此方法集成到我的 MainActivity.java 和 activity_main.xml 文件中。具体来说,在代码片段中,有mPosX和mPosY,我不知道如何使用这些全局变量。
我尝试创建一个扩展 View 类的新类并放置 onTouchEvent()。
我知道您可以使用 onDraw() 并覆盖它以在每次手指移动时利用 mPosX 和 mPosY 重绘对象,但我不知道具体如何。我需要一些实现 onDraw() 的示例代码。
这是我正在谈论的代码片段:
// The ‘active pointer’ is the one currently moving our object.
private int mActivePointerId = INVALID_POINTER_ID;
@Override
public boolean onTouchEvent(MotionEvent ev) {
// Let the ScaleGestureDetector inspect all events.
mScaleDetector.onTouchEvent(ev);
final int action = MotionEventCompat.getActionMasked(ev);
switch (action) {
case MotionEvent.ACTION_DOWN: {
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final float x = MotionEventCompat.getX(ev, pointerIndex);
final float y = MotionEventCompat.getY(ev, pointerIndex);
// Remember where we started (for dragging)
mLastTouchX = x;
mLastTouchY = y;
// Save the ID of this pointer (for dragging)
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
break;
}
case MotionEvent.ACTION_MOVE: {
// Find the index of the active pointer and fetch its position
final int pointerIndex =
MotionEventCompat.findPointerIndex(ev, mActivePointerId);
final float x = MotionEventCompat.getX(ev, pointerIndex);
final float y = MotionEventCompat.getY(ev, pointerIndex);
// Calculate the distance moved
final float dx = x - mLastTouchX;
final float dy = y - mLastTouchY;
mPosX += dx;
mPosY += dy;
invalidate();
// Remember this touch position for the next move event
mLastTouchX = x;
mLastTouchY = y;
break;
}
case MotionEvent.ACTION_UP: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_POINTER_UP: {
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mLastTouchX = MotionEventCompat.getX(ev, newPointerIndex);
mLastTouchY = MotionEventCompat.getY(ev, newPointerIndex);
mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
}
break;
}
}
return true;
}
解决方案
创建一个类 MoveViewTouchListener
public class MoveViewTouchListener
implements View.OnTouchListener
{
private GestureDetector mGestureDetector;
private View mView;
public MoveViewTouchListener(View view)
{
mGestureDetector = new GestureDetector(view.getContext(), mGestureListener);
mView = view;
}
@Override
public boolean onTouch(View v, MotionEvent event)
{
return mGestureDetector.onTouchEvent(event);
}
private GestureDetector.OnGestureListener mGestureListener = new GestureDetector.SimpleOnGestureListener()
{
private float mMotionDownX, mMotionDownY;
@Override
public boolean onDown(MotionEvent e)
{
mMotionDownX = e.getRawX() - mView.getTranslationX();
mMotionDownY = e.getRawY() - mView.getTranslationY();
Log.d("imageview"," down");
return true;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
{
mView.setTranslationX(e2.getRawX() - mMotionDownX);
mView.setTranslationY(e2.getRawY() - mMotionDownY);
if((distanceX==0)&&(distanceY==0))
{
Log.d("imageview"," zoomed");
}
return true;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
Log.d("imageview"," tapped");
return true;
}
};
}
在活动调用中:
ImageView imageView= findViewById(R.id.imageView);
imageView.setOnTouchListener(new MoveViewTouchListener(imageView));