在手机屏幕上能够实现的人机交互行为,大致包括点击按钮,拉动滑动块,物体缩放,上下左右拉动等。
手机屏幕触摸事件的监听方法:
1.首先要设置一块布局区域,frameLayout/LinearLayout等都可以,并为布局设置id;
2.在Activity中声明相应的布局类型,并通过findViewById()方法找到该布局,然后为该布局区域设置setOnTouchListener()方法,就能监听在相应屏幕触摸操作
实现屏幕触摸事件监听的代码:
private LinearLayout Land;
Land = (LinearLayout) findViewById(R.id.Land); Land.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) {
// event是当手指触摸到屏幕后,新建的对象,里面封装了一系列对屏幕的操作信息 switch(event.getAction()){ case MotionEvent.ACTION_DOWN: //当手指第一次按下的时候,执行的操作 break; case MotionEvent.ACTION_UP: //当手指抬起,离开屏幕的时候,执行的操作 break;
case MotionEvent.ACTION_MOVE:
//当手指一直按在屏幕上,并且移动的时候执行的操作
break;
} //这里设置为true表示一直监听这块区域的触摸行为,false则表示监听一次就不再监听 return true; } });
判断上下左右操作行为的方法:
在设置了setOnTouchListener()方法后,里面传进来的event中包含了所有手指对屏幕的操作信息,我们通过对event的解读,判断具体的操作行为。
具体的实现代码:
private float X1;
private float X2;
private float Y1; private float Y2; private float ComparedX; private float ComparedY; private LinearLayout Land; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Land = (LinearLayout) findViewById(R.id.Land); Land.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch(event.getAction()){ case MotionEvent.ACTION_DOWN: X1 = event.getX(); //获取刚按下屏幕位置的X坐标的值 Y1 = event.getY(); //获取刚按下屏幕位置的Y坐标的值 break; case MotionEvent.ACTION_UP: X2 = event.getX(); //当手指抬起时,再次获取屏幕位置的X值 Y2 = event.getY(); //同理 Action(X1,X2,Y1,Y2); break; } //设置一直监听此区域的触摸事件 return true; } }); } public void Action(float X1, float X2, float Y1, float Y2){ ComparedX = X2 - X1; //第二次的X坐标的位置减去第一次X坐标的位置,代表X坐标上的变化情况 ComparedY = Y2 -Y1; //同理
//当X坐标的变化量的绝对值大于Y坐标的变化量的绝对值,以X坐标的变化情况作为判断依据
//上下左右的判断,都在一条直线上,但手指的操作不可能划直线,所有选择变化量大的方向上的量
//作为判断依据
if (Math.abs(ComparedX) >= Math.abs(ComparedY)){ //leader X if (ComparedX>0){
//手机屏幕的坐标值,从左上方到右下方增加,横为X轴,竖为Y轴
Toast.makeText(MainActivity.this,"向右滑动",Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(getApplicationContext(),"向左滑动",Toast.LENGTH_SHORT).show(); } }else{ // leader Y if (ComparedY>0){ Toast.makeText(getApplicationContext(),"向下滑动",Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(getApplicationContext(),"向上滑动",Toast.LENGTH_SHORT).show(); } } }
缩放操作的实现:
识别上下左右的拉动操作,只需要监听一个手指的操作情况,但要实现缩放的识别需要监听两个手指。
但监听两个手指的操作行为,并不需要操作和补充监听的函数,因为event中包含了所有屏幕收到的操作信息,我们只需要更加细致的解读event就能实现缩放的判断。
缩放的具体实现代码:
Touch.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: break; case MotionEvent.ACTION_UP: break; case MotionEvent.ACTION_MOVE:
//在手指一直放在屏幕上的动作中设置缩放操作,则缩放的操作是渐变的
if (event.getPointerCount()>=2){ //获取一共几个触摸点,只有当触摸的点大于等于两个,才判断缩放行为
//event中封存了所有屏幕被触摸的点的信息,第一个触摸的位置可以通过event.getX(0)/getY(0)得到
float offSetX = event.getX(0) - event.getX(1); float offSetY = event.getY(0) - event.getY(1); //运用三角函数的公式,通过计算X,Y坐标的差值,计算两点间的距离 currentdistance = (float) Math.sqrt(offSetX*offSetX+offSetY*offSetY); if (lastDistance < 0){//如果是第一次进行判断 lastDistance = currentdistance; }else{
//之所以大于10才执行,是为了给出一个缓冲时间,设置一个变化读取的阀值
//否则会出现手指放在上面不动,而被操作的图片却一直在不断的放大缩小的情况 if (currentdistance-lastDistance>10){ FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) iv.getLayoutParams(); //这里必须要使用这种写法,否则屏幕的宽度和长度返回的是指int数据,而1.1为float型
//直接计算,会抛弃小数部分,导致毫无变化
//若是有其他方法能使得int和float数据之间顺利计算,也是可以的
lp.width= (int) (1.1f*iv.getWidth()); lp.height= (int) (1.1f*iv.getHeight());
//安卓中设计参数的修改和设定,都是通过parameters的属性来实现 iv.setLayoutParams(lp); Log.e(Tag,"fangda"); }else if (lastDistance-currentdistance>10){ FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) iv.getLayoutParams(); lp.width= (int) (0.9f*iv.getWidth()); lp.height= (int) (0.9f*iv.getHeight()); iv.setLayoutParams(lp); Log.e(Tag,"suoxiao"); } } //在一次缩放操作完成后,将本次的距离赋值给lastDistance,以便下一次判断
//但这种方法写在move动作中,意味着手指一直没有抬起,监控两手指之间的变化距离超过10
//就执行缩放操作,不是在两次点击之间的距离变化来判断缩放操作
//故这种将本次距离留待下一次判断的方法,不能在两次点击之间使用
lastDistance = currentdistance; } break; } return true; } });