MotionEvent(二) 多点触摸

多点触摸和单点触摸的机制一样,都是为触摸事件创建MotionEvent对象,并将这些MotionEvent对象传递给各种方法。

多点触摸的2个重要概念是指针索引和指针ID

指针索引:android把多点触摸时的一个手指抽象成一个“指针”,这个指针有其索引,从0开始。这个索引分配给对应的手指之后,值是会随着手指数量的增减而改变的。如果同时有2根手指在屏幕上,第一根手指指针索引为0,第二根为1,如果第一根手指离开屏幕,第二根的指针索引变为0,因为此刻屏幕上只有1根手指

指针ID:唯一标识一根手指的id,相当于表的主键,这个值和索引不一样,是不会变的。

指针索引和指针ID的关系就像是数据库表中的记录的行号和其主键,删除一条记录,其他记录的行号会发生变化,但是他们的ID是唯一的。


对于多点触摸,MotionEvent中常用到的方法:

getPointerCount():返回MotionEvent中表示了多少手指数

getPointerId(int pointerIndex): 返回指针索引关联的指针ID

getY(int pointerIndex):返回指定指针索引的当前的Y坐标位置

getX(int pointerIndex):返回指定指针索引的当前的X坐标位置

getHistorySize():返回某跟手指触摸事件的历史位置的记录数

getHistoricalX (int pointerIndex, int pos):返回指定指针索引的手指上一次的X坐标位置,只针对移动事件。参数pos是指第几个旧位置,这个值不能超过getHistorySize()返回的值
getHistoricalY (int pointerIndex, int pos):返回指定指针索引的手指上一次的Y坐标位置,只针对移动事件。参数pos是指第几个旧位置,这个值不能超过getHistorySize()返回的值


测试代码:

布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity"
    android:id="@+id/relativelayout"
     >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</RelativeLayout>

MainActivity.java:

public class MainActivity extends Activity implements OnTouchListener{

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		RelativeLayout r = (RelativeLayout)findViewById(R.id.relativelayout);
		r.setOnTouchListener(this);
	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		StringBuilder result = new StringBuilder(500);
		//手指的动作
		int action = event.getAction();
		//几根手指
		int points = event.getPointerCount();
		result.append("action:" + action).append(",point_count:"+points);
		//输出此刻所有手指的状态
		for (int i = 0; i < points; i++) {
			result.append(",index:").append(i).append(",id:"+ event.getPointerId(i));
			result.append(",getX:").append(event.getX(i)).append(",getY:")
			.append(event.getY(i));
		}
		Log.v("test", "---------------------------------------");
		Log.v("test", result.toString());
		return true;
	}
}

现在运行程序,然后放上一根手指在屏幕上,再放一根上去。再依次松开手指,查看日志输出

06-18 23:55:35.612: V/test(10138): ---------------------------------------
06-18 23:55:35.612: V/test(10138): action:0,point_count:1,index:0,id:0,getX:202.0,getY:417.0
06-18 23:55:35.622: V/test(10138): ---------------------------------------
06-18 23:55:35.622: V/test(10138): action:2,point_count:1,index:0,id:0,getX:209.0,getY:418.0
06-18 23:55:35.652: V/test(10138): ---------------------------------------
06-18 23:55:35.652: V/test(10138): action:2,point_count:1,index:0,id:0,getX:212.0,getY:419.0
06-18 23:55:35.662: V/test(10138): ---------------------------------------
06-18 23:55:35.662: V/test(10138): action:2,point_count:1,index:0,id:0,getX:214.0,getY:420.0
06-18 23:55:35.682: V/test(10138): ---------------------------------------
06-18 23:55:35.682: V/test(10138): action:2,point_count:1,index:0,id:0,getX:212.0,getY:419.0
06-18 23:55:35.742: V/test(10138): ---------------------------------------
06-18 23:55:35.742: V/test(10138): action:2,point_count:1,index:0,id:0,getX:215.0,getY:422.0
06-18 23:55:35.772: V/test(10138): ---------------------------------------
06-18 23:55:35.772: V/test(10138): action:2,point_count:1,index:0,id:0,getX:218.0,getY:426.0
06-18 23:55:35.792: V/test(10138): ---------------------------------------
06-18 23:55:35.792: V/test(10138): action:2,point_count:1,index:0,id:0,getX:221.0,getY:428.0
06-18 23:55:35.812: V/test(10138): ---------------------------------------
06-18 23:55:35.812: V/test(10138): action:2,point_count:1,index:0,id:0,getX:223.0,getY:430.0
06-18 23:55:35.832: V/test(10138): ---------------------------------------
06-18 23:55:35.832: V/test(10138): action:2,point_count:1,index:0,id:0,getX:225.0,getY:433.0
06-18 23:55:35.842: V/test(10138): ---------------------------------------
06-18 23:55:35.842: V/test(10138): action:2,point_count:1,index:0,id:0,getX:226.0,getY:435.0
06-18 23:55:35.862: V/test(10138): ---------------------------------------
06-18 23:55:35.862: V/test(10138): action:2,point_count:1,index:0,id:0,getX:227.0,getY:436.0
06-18 23:55:35.882: V/test(10138): ---------------------------------------
06-18 23:55:35.882: V/test(10138): action:2,point_count:1,index:0,id:0,getX:228.0,getY:438.0
06-18 23:55:35.902: V/test(10138): ---------------------------------------
06-18 23:55:35.902: V/test(10138): action:2,point_count:1,index:0,id:0,getX:228.0,getY:439.0
06-18 23:55:35.942: V/test(10138): ---------------------------------------
06-18 23:55:35.942: V/test(10138): action:2,point_count:1,index:0,id:0,getX:227.0,getY:440.0
06-18 23:55:35.972: V/test(10138): ---------------------------------------
06-18 23:55:35.972: V/test(10138): action:2,point_count:1,index:0,id:0,getX:227.0,getY:441.0
06-18 23:55:36.002: V/test(10138): ---------------------------------------
06-18 23:55:36.002: V/test(10138): action:2,point_count:1,index:0,id:0,getX:226.0,getY:441.0
06-18 23:55:36.032: V/test(10138): ---------------------------------------
06-18 23:55:36.032: V/test(10138): action:2,point_count:1,index:0,id:0,getX:227.0,getY:442.0
06-18 23:55:36.072: V/test(10138): ---------------------------------------
06-18 23:55:36.072: V/test(10138): action:2,point_count:1,index:0,id:0,getX:228.0,getY:443.0
06-18 23:55:36.072: V/test(10138): ---------------------------------------
06-18 23:55:36.072: V/test(10138): action:261,point_count:2,index:0,id:0,getX:228.0,getY:443.0,index:1,id:1,getX:388.0,getY:218.0
06-18 23:55:36.092: V/test(10138): ---------------------------------------
06-18 23:55:36.092: V/test(10138): action:2,point_count:2,index:0,id:0,getX:228.0,getY:444.0,index:1,id:1,getX:391.0,getY:222.0
06-18 23:55:36.112: V/test(10138): ---------------------------------------
06-18 23:55:36.112: V/test(10138): action:2,point_count:2,index:0,id:0,getX:228.0,getY:445.0,index:1,id:1,getX:391.0,getY:227.0
06-18 23:55:36.122: V/test(10138): ---------------------------------------
06-18 23:55:36.122: V/test(10138): action:2,point_count:2,index:0,id:0,getX:228.0,getY:447.0,index:1,id:1,getX:397.0,getY:235.0
06-18 23:55:36.142: V/test(10138): ---------------------------------------
06-18 23:55:36.142: V/test(10138): action:2,point_count:2,index:0,id:0,getX:228.0,getY:448.0,index:1,id:1,getX:402.0,getY:245.0
06-18 23:55:36.162: V/test(10138): ---------------------------------------
06-18 23:55:36.162: V/test(10138): action:2,point_count:2,index:0,id:0,getX:227.0,getY:449.0,index:1,id:1,getX:407.0,getY:257.0
06-18 23:55:36.182: V/test(10138): ---------------------------------------
06-18 23:55:36.182: V/test(10138): action:2,point_count:2,index:0,id:0,getX:227.0,getY:450.0,index:1,id:1,getX:414.0,getY:269.0
06-18 23:55:36.202: V/test(10138): ---------------------------------------
06-18 23:55:36.202: V/test(10138): action:2,point_count:2,index:0,id:0,getX:227.0,getY:452.0,index:1,id:1,getX:421.0,getY:279.0
06-18 23:55:36.212: V/test(10138): ---------------------------------------
06-18 23:55:36.212: V/test(10138): action:2,point_count:2,index:0,id:0,getX:227.0,getY:453.0,index:1,id:1,getX:428.0,getY:289.0
06-18 23:55:36.232: V/test(10138): ---------------------------------------
06-18 23:55:36.232: V/test(10138): action:2,point_count:2,index:0,id:0,getX:227.0,getY:455.0,index:1,id:1,getX:434.0,getY:296.0
06-18 23:55:36.252: V/test(10138): ---------------------------------------
06-18 23:55:36.252: V/test(10138): action:2,point_count:2,index:0,id:0,getX:226.0,getY:456.0,index:1,id:1,getX:440.0,getY:302.0
06-18 23:55:36.272: V/test(10138): ---------------------------------------
06-18 23:55:36.272: V/test(10138): action:2,point_count:2,index:0,id:0,getX:226.0,getY:457.0,index:1,id:1,getX:439.0,getY:308.0
06-18 23:55:36.292: V/test(10138): ---------------------------------------
06-18 23:55:36.292: V/test(10138): action:6,point_count:2,index:0,id:0,getX:226.0,getY:457.0,index:1,id:1,getX:439.0,getY:308.0
06-18 23:55:36.292: V/test(10138): ---------------------------------------
06-18 23:55:36.292: V/test(10138): action:1,point_count:1,index:0,id:1,getX:439.0,getY:308.0

红色标注的部分,action261,是在第二根手指放上屏幕的时候,为什么是261呢,看下261转成16进制:0X00000105,这个action由2部分掩码组成,指针索引0x00000100(第2个手指的索引)和操作的常量值ACTION_POINTER_DOWN(0x00000005),当第二根手指触屏时是多点触摸,所以动作是ACTION_POINTER_DOWN而不是ACTION_DOWN。

action:6,此时正是第一根手指离开屏幕,所以action掩码是0x00000000(第一个手指的索引)|0x00000006(ACTION_POINTER_UP),再看下一组输出, action:1,此时屏幕上只有一根手指了,并且离开屏幕,所以action是ACTION_UP。注意到index=0,id=1,和一开始的index=1,id=1不同了,index因为只剩一根手指所以变成了0,这说明了指针索引是不断变化的。

另外,输出历史位置,并没有得到想要的输出,不知道有没有解决过此问题的仁兄,求教

		Log.v("test", event.getHistorySize()+"");
		for (int j = 0; j < event.getHistorySize(); j++) {
			for (int i = 0; i < points; i++) {
				result2.append(",index:").append(i).append(",id:"+ event.getPointerId(i));
				result2.append(",getHistoricalX:").append(event.getHistoricalX(i, j))
				.append(",getHistoricalY:").append(event.getHistoricalY(i, j));
			}
		}
		Log.v("test", "---------------------------------------");
		Log.v("test", result2.toString());


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值