运行有问题或需要源码请点赞关注收藏后评论区留言~~~
一、辨别缩放与旋转手势
一个手指的滑动只能识别手势的滑动方向,两个手指的滑动才能识别更复杂的手势动作,如两个手指张开可表示放大操作,两个手指并拢可以表示缩小操作,两个手指交错旋转表示旋转操作,而旋转方向又可以细分为顺时针旋转和逆时针旋转
由于两个手指各有自己的按下与松开事件,都有对应的触摸起点和终点,因此只能依次记录两个手指的起点与终点坐标,根据着四个点的位置关系就能算出手势的动作类别,至于缩放类型与旋转手势的区分,则需要计算第一个手势起点和终点的连线,以及第二个手势起点和终点的连线,再判断两根连线是倾向于在相同方向上缩放还是倾向于绕着连线中点旋转
判别示意图如下
运行效果如下
虚拟机可以按住ctrl和鼠标左键模仿操作,当然连接真机操作更加便捷
代码如下
Java类
package com.example.event; import androidx.appcompat.app.AppCompatActivity; import android.annotation.SuppressLint; import android.graphics.PointF; import android.os.Bundle; import android.widget.TextView; import com.example.event.util.PointUtil; import com.example.event.widget.MultiTouchView; @SuppressLint("DefaultLocale") public class ScaleRotateActivity extends AppCompatActivity { private TextView tv_desc; // 声明一个文本视图对象 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_scale_rotate); tv_desc = findViewById(R.id.tv_desc); MultiTouchView mtv_gesture = findViewById(R.id.mtv_gesture); // 设置多点触摸视图的手势滑动监听器 mtv_gesture.setSlideListener((firstBeginP, firstEndP, secondBeginP, secondEndP) -> { // 上次两个触摸点之间的距离 float preWholeDistance = PointUtil.distance(firstBeginP, secondBeginP); // 当前两个触摸点之间的距离 float nowWholeDistance = PointUtil.distance(firstEndP, secondEndP); // 主要点在前后两次落点之间的距离 float primaryDistance = PointUtil.distance(firstBeginP, firstEndP); // 次要点在前后两次落点之间的距离 float secondaryDistance = PointUtil.distance(secondBeginP, secondEndP); if (Math.abs(nowWholeDistance - preWholeDistance) > (float) Math.sqrt(2) / 2.0f * (primaryDistance + secondaryDistance)) { // 倾向于在原始线段的相同方向上移动,则判作缩放动作 float scaleRatio = nowWholeDistance / preWholeDistance; String desc = String.format("本次手势为缩放动作,%s为%f", scaleRatio>=1?"放大倍数":"缩小比例", scaleRatio); tv_desc.setText(desc); } else { // 倾向于在原始线段的垂直方向上移动,则判作旋转动作 // 计算上次触摸事件的旋转角度 int preDegree = PointUtil.degree(firstBeginP, secondBeginP); // 计算本次触摸事件的旋转角度 int nowDegree = PointUtil.degree(firstEndP, secondEndP); String desc = String.format("本次手势为旋转动作,%s方向旋转了%d度", nowDegree>preDegree?"顺时针":"逆时针", Math.abs(nowDegree-preDegree)); tv_desc.setText(desc); } }); } }
XML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/tv_desc" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="5dp" android:text="请两指同时按压并缩放或旋转,再观察手势结果" android:textColor="@color/black" android:textSize="17sp" /> <com.example.event.widget.MultiTouchView android:id="@+id/mtv_gesture" android:layout_width="match_parent" android:layout_height="300dp" android:background="@color/white" /> </LinearLayout>
创作不易 觉得有帮助请点赞关注收藏~~~