写点什么

自定义 View:多点触摸与实现任意拖动图片控

作者:Changing Lin
  • 2021 年 11 月 16 日
  • 本文字数:1831 字

    阅读完需:约 6 分钟

1.知识点

  • 触摸事件是按序列来分组的,每⼀组事件必然以 ACTION_DOWN 开头,以 ACTION_UP 或 ACTION_CANCEL 结束。

  • 触摸事件序列是针对 View 的,⽽不是针对 Pointer 的。

  • MotionEvent.getActionIndex():表示第几个触摸点,为了遍历

  • MotionEvent.getPointerId():表示第几个触摸点的 ID,

  • MotionEvent.getPointerCount():表示总共有几个触摸点

2.原理

  • 多点触摸的情况下,会触发 View 的 ACTION_POINTER_DOWN 和 ACTION_POINTER_UP 事件

3.如何实现图片跟随手指移动

  • 方法一:在 ACTION_DOWN 事件时,记录起始的位置;在 ACTION_MOVE 事件时,计算相对起始位置的偏移量,从而实现图片跟随手指移动。如第 4 点代码所示。

  • 方法二:如下代码所示,直接关联触摸点位置与图片的偏移。这种方式简单但存在缺点,当前位置的坐标有两种,一种是相对于屏幕(getRawX),一种是相对于 View(getX)。需要考虑屏幕的状态栏高度和 ActionBar 的高度。

		@Override    public boolean onTouchEvent(MotionEvent event) {        int masked = event.getActionMasked();
switch (masked){ case MotionEvent.ACTION_MOVE: offsetX = event.getX(); offsetY = event.getY(); invalidate(); break; default:break; } return true; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawBitmap(bitmap, offsetX-IMAGE_WIDTH/2, offsetY-IMAGE_WIDTH/2, paint); }
复制代码

4.实现多点触摸的跟踪最新点拖动图片

package com.besmart.components;
import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Paint;import android.util.AttributeSet;import android.util.Log;import android.view.MotionEvent;import android.view.View;
import androidx.annotation.Nullable;
public class TestView extends View { private static final String TAG = "TestView"; private static final float IMAGE_WIDTH = Util.dp2px(200); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); Bitmap bitmap; float downX; float downY; float offsetX; float offsetY; float orgOffsetX; float orgOffsetY;
int statusBarHeight;
{ bitmap = Util.getImage(getResources(), (int) IMAGE_WIDTH, R.drawable.he); }
public TestView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); statusBarHeight = Util.getStatusBarHeight(context); }
@Override public boolean onTouchEvent(MotionEvent event) { int masked = event.getActionMasked(); int index = event.getActionIndex(); int id = event.getPointerId(index);
switch (masked){ case MotionEvent.ACTION_DOWN: downX = event.getX(); downY = event.getY(); orgOffsetX = offsetX; orgOffsetY = offsetY; break; case MotionEvent.ACTION_MOVE: int count = event.getPointerCount(); Log.e(TAG, String.format("onTouchEvent: ACTION_MOVE %d-%d-%d", index, id, count));
offsetX = orgOffsetX + event.getX(count-1) - downX; offsetY = orgOffsetY + event.getY(count-1) - downY; invalidate(); break; case MotionEvent.ACTION_POINTER_DOWN: Log.e(TAG, String.format("onTouchEvent: ACTION_POINTER_DOWN %d-%d", index, id)); break;
case MotionEvent.ACTION_POINTER_UP: Log.e(TAG, String.format("onTouchEvent: ACTION_POINTER_UP %d-%d", index, id)); break; default:break; } return true; }
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawBitmap(bitmap, offsetX, offsetY, paint); }}
复制代码


发布于: 5 小时前阅读数: 6
用户头像

Changing Lin

关注

获得机遇的手段远超于固有常规之上~ 2020.04.29 加入

我能做的,就是调整好自己的精神状态,以最佳的面貌去面对那些未曾经历过得事情,对生活充满热情和希望。

评论

发布
暂无评论
自定义View:多点触摸与实现任意拖动图片控