Android触摸事件是建立于Ontuch事件相应机制上的,首先我们需要为Activity窗体添加一个OnTouchListener,实现OnTouchListener接口即可
1 2 3 4 5 6 7 8 9 10 11 | public class MainActivity extends Activity implements OnTouchListener { Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = (Button) findViewById(R.id.button1); button.setOnTouchListener(this); } } |
如果监听的是控件的触摸事件,我们可以将对应的按钮绑定进OnTouch监听中,即完成了OnTouchListener的添加。
Activity继承了OnTouchListener事件后,需要实现其onTouch(View v, MotionEvent event)方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub if (event.getAction() == MotionEvent.ACTION_DOWN) { switch (v.getId()) { case R.id.button1: // 触发此按钮的Touch Down事件 break; default: break; } } else if (event.getAction() == MotionEvent.ACTION_UP) { switch (v.getId()) { case R.id.button1: // 触发此按钮的Touch Up事件 break; default: break; } } } |
以上即是Android中为某一控件添加OnTouch事件的基础方法。
完成以上工作之后,我们继续根据这个框架的拓展创建一个自己的OnTouch触摸屏程序。
下面介绍另一种触摸监听的方法,此方法适用于对整个屏幕的触摸。
由于最近项目需要,这里就做一个获取触摸位移向量的换算程序。此方案主要应用于一些第一人称游戏的视角移动,玩家通过触摸屏幕即可像在PC上移动鼠标一样实现类似CS游戏中的视角控制。
基本原理是:获取玩家第一次触摸在屏幕的坐标原点,当玩家OnTouch_Move时,实时监听当前坐标,并与第一次点击的原点坐标进行对比,形成一个方向向量,程序根据此向量判断玩家手指向某个方向move,以此将游戏视角与move方向进行匹配。
同时,游戏视角的旋转度数,也与玩家手指相对于手机屏幕move的百分比相匹配,以此做到视角控制上的同步感。
这个demo也可以应用在机器人小车的摄像头控制上,从而做到类似第一人称游戏的效果。
监听屏幕的触摸事件和控件中的有些不一样,我们不需要实现onTouchListener接口,只需要重载Acitvity的onTouchEvent函数即可,代码如下:
1 2 3 4 5 | @Override public boolean onTouchEvent(MotionEvent event){ Log.d("X:"+event.getX(), ",Y:"+event.getY()); return true; } |
此时触摸屏幕,Log中会实际时输出触摸点相对于屏幕的坐标。
了解此框架以后我们开始拓展
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | @Override public boolean onTouchEvent(MotionEvent event){ switch (event.getAction()) { case MotionEvent.ACTION_DOWN: Log.d("Down",":" + event.getY() + "," + event.getX()); break; case MotionEvent.ACTION_MOVE: Log.d("Move",":" + event.getY() + "," + event.getX()); break; case MotionEvent.ACTION_UP: Log.d("Up",":" + event.getY() + "," + event.getX()); break; } return true; } |
此时我们将对触摸屏幕的三种状态进行分类。这个就是整个位移控制的核心框架了,接下来,嵌入相应的逻辑部分,
最终代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | @Override public boolean onTouchEvent(MotionEvent event){ switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //获取初始点位置 xP0 = event.getX(); yP0 = event.getY(); Log.d("Down",":" + event.getY() + "," + event.getX()); break; case MotionEvent.ACTION_MOVE: //将相对位移换算成角度移动 float xAngle = (event.getX() - xP0) / wWidth * 360; float yAngle = (event.getY() - yP0) / wHeight * 360; Log.d("Move","->" + xAngle + "° :" + yAngle + "°"); break; case MotionEvent.ACTION_UP: //初始点归零 xP0 = 0; yP0 = 0; Log.d("Up",":" + wWidth + "," + wHeight); break; } return true; } |
这里顺带说一下wWidth,wHeight这两个变量,分别是Activity的宽和高,wWidth * 360 的意思是:滑动一个屏幕宽度的距离可以使视角正好旋转360度,这里的度数可以根据灵敏度要求调整另设。
最后补充一下获取Activity长宽的代码:
1 2 3 4 | DisplayMetrics dm = new DisplayMetrics(); this.getWindowManager().getDefaultDisplay().getMetrics(dm); wWidth = dm.widthPixels; wHeight = dm.heightPixels; |
通过此框架,我们即可通过Android触摸屏来控制任意摄像机的旋转角度。关于细节的微调,还需要大家自己去完善,本篇就到这里,欢迎交流讨论,谢谢关注。
BeiTown
2013.04.23
Tags: Android, Arduino, onTouchEvent, OnTouchListener, 游戏视角, 获取Activity宽度, 触摸事件