多点触控手势识别_Android:多点触控手势控制器

多点触控手势识别

很少有我们的项目 (我们的项目或针对客户的项目 )实现多点触摸功能,以通过标准手势(拖放,旋转,缩放)来操纵图像。 尽管多点触摸控制器的实现具有挑战性和趣味性,但它会花费大量时间,并且如果有准备就绪且简单可行的方法,为什么还要重新发明轮子呢? 因此,我们决定进行一些研究,以查看其中哪个开源项目最适合我们的需求。 在不提及我们不喜欢并没有引人注目的控制器和项目的情况下,我要提到的是,我们之前构建的几个演示项目的经验表明,最好的多点触摸控制器具有易于实现的逻辑并且易于实现。了解语法的是Luke HutchisonAndroid Multitouch Controller 。 这些源可根据MIT许可的条款获得。

什么是多点触控控制器?

该术语不通用。 我们所说的“多点触摸控制器”是一段代码,它使在屏幕上显示的实体(视图,位图等)上实现操纵操作的过程变得很方便。 这意味着多点触摸控制器将逻辑包装在通过触摸屏的用户输入后面。 因此,当用户放下一根手指并开始在触摸屏上移动手指时,控制器应“指向”部分代码,开发人员应将自己的逻辑放在他想发生的事情上。 控制器“知道”是单指触摸,捏手势或旋转手势,还是一次(只要有可能)全部手势。 更准确地说,通过将库或代码链接到您的应用,多点触摸控制器不会使您的图形神奇地在屏幕上移动。 可以将其视为需要实现的接口,以便使对象移动,但是您需要弄清楚如何实现。

我们已经选择的已经提到的多点触控控制器是Android Multitouch Controller 。 准备时首先需要做的是创建一个空的Android项目并下载MultiTouchController.java文件。 这里是本教程所需要的90%。

生活必需品

到目前为止,通过使用批处理资源(可绘制对象)给出了Android Multitouch Controller的示例,可以稍后在Canvas上对其进行修改。 我们的想法是简化此过程,并在画布上仅制作一个可移动对象。 因此,我们将使用简单的位图,该位图将绘制在画布上,随后可以从其初始位置进行移动/缩放/旋转。 因此,我们首先需要两件事:一个实现MultiTouchObjectCanvas接口的View,然后一个将包含其绘制逻辑的自定义对象/实体/小部件。 该对象是“操纵性”对象,它包含代表它的位图。

因此,当我们说C 语言时,我们想到了需要创建的自定义视图,该视图将实现MultiTouchObjectCanvas接口(其中T是要修改的Pinch对象)。 该界面告诉我们在用户触摸屏幕时是否有对象(可拖动对象)或小部件。 如果是这样,则实现将返回相关对象,否则返回null。 因此,要使用此接口,我们需要实现几种方法,否则我们将无法获得结果。 无论如何,IDE会告诉您必须实现的内容,这些是方法(在父级View类的构造函数等中):

@Override 
public T getDraggableObjectAtPoint(PointInfo touchPoint) { 
        return null; 
}

如您所见,此方法从用户进行触摸输入的位置返回感兴趣的对象。 这意味着,如果用户触摸了x:120; y:100点,则此方法应检查该点是否在窗口小部件占用的区域中。 当您看到完整的实现时,您将知道它是如何完成的。

@Override
public void getPositionAndScale(T obj, 
        PositionAndScale objPosAndScaleOut) {
}

此方法对被触摸的小部件的PositionAndScale对象进行操作。 小部件作为第一个参数传递,而PositionAndScale作为第二个参数传递,这几乎是自描述性的:当触摸“ obj”对象时,将“ objPosAndScaleOut”属性应用于位置,比例和角度。 但这仅适用于屏幕的初始位置,实际上使运动成为第二种强制性方法。

@Override
public boolean setPositionAndScale(T obj,
 PositionAndScale newObjPosAndScale, PointInfo touchPoint) {
 return false;
}

同样,我们将小部件作为第一个参数,将新对象的位置/比例/角度属性以及PointInfo的帮助对象告知其是多点触摸还是单(拖动)手势。

@Override
public void selectObject(T obj, PointInfo touchPoint) {
}

此方法负责通知控制器正在选择哪个对象。 'obj'对象具有选定的对象。 因此,当我们实现此方法并设置多点触控控制器对象时,我们可以实现小部件逻辑,该逻辑将数据保存在画布上绘制的项目后面。 是的,在这种情况下,我们需要一个MultiTouchController对象,需要这样定义:

private MultiTouchController
        
          mMultiTouchController = new MultiTouchController
         
          (this);

那该怎么办? 好吧,当触摸事件发生时,我们需要将“一切”传递给该控制器。 这是通过覆盖自定义View / Canvas的onTouchEvent来完成的:

@Override
public boolean onTouchEvent(MotionEvent ev) {
 return mMultiTouchController.onTouchEvent(ev);
}

有了这些人员和其他几个工作人员,我们有了基本的Canvas,可以处理它绘制的对象。 因此,我们还需要一件事,即Pinch小部件的逻辑及其位图,坐标等。因此,我们创建了一个PinchWidget对象,该对象是Multitouch Controller附带的一些示例的修改。 该对象的本质是以下两种方法:

public boolean setPos(PositionAndScale newImgPosAndScale, int uiMode, int uiModeAnisotropic, boolean isMultitouch) {
 boolean ret = false;
 float x = newImgPosAndScale.getXOff();
 float y = newImgPosAndScale.getYOff();
 if(isMultitouch) {
  x = mCenterX;
  y = mCenterY;
 }

 ret = setPos(x, y, 
  (uiMode & uiModeAnisotropic) != 0 ? newImgPosAndScale.getScaleX() : newImgPosAndScale.getScale(),
   (uiMode & uiModeAnisotropic) != 0 ? newImgPosAndScale.getScaleY() : newImgPosAndScale.getScale(), 
    newImgPosAndScale.getAngle());

 return ret;
}

private boolean setPos(float centerX, float centerY, float scaleX, float scaleY, float angle) {
 float ws = (mImage.getWidth() / 2) * scaleX, hs = (mImage.getHeight() / 2) * scaleY;
 float newMinX = centerX - ws, newMinY = centerY - hs, newMaxX = centerX + ws, newMaxY = centerY + hs;
 mCenterX = centerX;
 mCenterY = centerY;
 mScaleFactor = scaleX;
 mAngle = angle;

 mMinX = newMinX;
 mMinY = newMinY;
 mMaxX = newMaxX;
 mMaxY = newMaxY;

 return true;
}

这两种方法使移动成为可能,因为它们提供了有关PinchWidget的坐标,比例因子和角度的信息。 它们以某种方式耦合在一起,这意味着第一种方法对其从第二种方法获得的数据进行计算。 现在我们有了对象的坐标,比例和角度。 我们只需要使用其draw(Canvas)方法来绘制它:

public void draw(Canvas canvas) {
 Paint itemPaint = new Paint();
 itemPaint.setAntiAlias(true);
 itemPaint.setFilterBitmap(true);

 float dx = (mMaxX + mMinX) / 2;
 float dy = (mMaxY + mMinY) / 2;

 canvas.save();

 canvas.translate(dx, dy);
 canvas.rotate(mAngle * 180.0f / (float) Math.PI);
 canvas.translate(-dx, -dy);

 Rect srcRect = new Rect(0, 0, mImage.getWidth(), mImage.getHeight());
 Rect dstRect = new Rect((int) mMinX, (int) mMinY, (int) mMaxX, (int) mMaxY);

 canvas.drawBitmap(mImage, srcRect, dstRect, null);

 canvas.restore();
}

mImage是我们绘制的项目/小部件的位图。 必须画出看到的东西。 为了绘制它,我们需要它的源代码和目标代码(在这种实现中)。 源是图像的大小(在我们的示例中为Rect [0,0,300,300]),而目的地(将在何处绘制)是根据PinchWidget的init和setPos方法计算得出的。 然后,使用drawBitmap(…)方法以与绘制任何其他Bitmap相同的方式绘制图像。 现在回到MultiTouchView实现。 如前所述,请记住我们已经以XML声明了此View,我们将使用:

public MultiTouchView(Context context, AttributeSet attrs)

构造函数。 在那里,我们初始化上下文。 我们也有这种方法:

public void setPinchWidget(Bitmap bitmap) {
 mPinchWidget = new PinchWidget(bitmap);
 mPinchWidget.init(mContext.getResources());
}

该方法告诉M​​ultiTouchView什么是我们的PinchWidget。 它是在此创建的,并通过调用init()(此处的资源仅用于计算显示器的宽度和高度),我们将调用绘制小部件的整个机制。 在此视图中,其onDraw()方法中发生了以下情况:

@Override
public void onDraw(Canvas canvas) {
 super.onDraw(canvas);
  
 canvas.drawColor(Color.WHITE);
 mPinchWidget.draw(canvas);
}

很简单,不是吗? 因此,如果一切按说明进行,并且您了解了这种实现的背后思想,那么您将在屏幕上看到类似以下内容的内容:


结论

Android中的MultiTouch操作与其他平台上的数学运算基本相同。 但是,当您需要时间进行此类项目时,Android Multitouch Contoroller是省时的工具,并且在下载该工具时,请务必阅读记录在案的方法,并查看优美而优美的代码,并且不要忘记感谢开发人员做了。

也许值得一提的是,我们的研究花了将近1年(准确地说是9个月)来确定我们现在和将来的应用中需要使用哪种Multitouch Controller。

示例应用程序的源可在我们的GitHub存储库中找到 。 接下来,我们将尝试介绍在Canvas视图上显示许多位图所需要做的事情。 或者,如果您自己解决问题,请不要犹豫编写教程,我们很乐意在此处发布。

祝您编程愉快,别忘了分享!

参考: Android:我们的JCG合作伙伴 Aleksandar Balalovski在2dwarfs博客上提供了多点触摸手势控制器


翻译自: https://www.javacodegeeks.com/2012/10/android-multi-touch-gestures-controller.html

多点触控手势识别

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值