文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android 的触摸事件详解及示例代码

2022-06-06 07:35

关注

由于触摸(Touch)而触发的事件

Android的事件:onClick, onScroll,onFling等等,都是由许多个Touch组成的。其中Touch的第一个状态肯定是ACTION_DOWN,表示按下了屏幕。之后,touch将会有后续事件,可能是:

ACTION_MOVE //表示为移动手势

ACTION_UP //表示为离开屏幕

ACTION_CANCEL //表示取消手势,不会由用户产生,而是由程序产生的

一个Action_DOWN, n个ACTION_MOVE, 1个ACTION_UP,就构成了Android中众多的事件。

对于ViewGroup类的控件,有一个很重要的方法,就是onInterceptTouchEvent(),用于处理事件并改变事件的传递方向,它的返回值是一个布尔值,决定了Touch事件是否要向它包含的子View继续传递,这个方法是从父View向子View传递。

而方法onTouchEvent(),用于接收事件并处理,它的返回值也是一个布尔值,决定了事件及后续事件是否继续向上传递,这个方法是从子View向父View传递。

touch事件在onInterceptTouchEvent()和onTouchEvent以及各个childView间的传递机制完全取决于onInterceptTouchEvent()和onTouchEvent()的返回值。返回值为true表示事件被正确接收和处理了,返回值为false表示事件没有被处理,将继续传递下去。

ACTION_DOWN事件会传到某个ViewGroup类的onInterceptTouchEvent,如果返回false,则DOWN事件继续向子ViewGroup类的onInterceptTouchEvent传递,如果子View不是ViewGroup类的控件,则传递给它的onTouchEvent。

如果onInterceptTouchEvent返回了true,则DOWN事件传递给它的onTouchEvent,不再继续传递,并且之后的后续事件也都传递给它的onTouchEvent。

如果某View的onTouchEvent返回了false,则DOWN事件继续向其父ViewGroup类的onTouchEvent传递;如果返回了true,则后续事件会直接传递给其onTouchEvent继续处理。(后续事件只会传递给对于必要事件ACTION_DOWN返回了true的onTouchEvent)

总结一下就是:onInterceptTouchEvent可以接受到所有的Touch事件,而onTouchEvent则不一定。

对于android 自定义控件的事件 android提供了一个GestureDetector的类和GestureDetector.OnGestureListener的接口来判断用户在界面上做出怎么样的动作。

Android里有两个类

  android.view.GestureDetector
  android.view.GestureDetector.SimpleOnGestureListener
  (另外android.widget.Gallery好像是更牛x的OnGestureListener )

  1) 新建一个类继承SimpleOnGestureListener,HahaGestureDetectorListener 

     可以实现以下event事件。
  boolean onDoubleTap(MotionEvent e)
  解释:双击的第二下Touch down时触发
  boolean onDoubleTapEvent(MotionEvent e)
  解释:双击的第二下Touch down和up都会触发,可用e.getAction()区分。
  boolean onDown(MotionEvent e)
  解释:Touch down时触发
  boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY)
  解释:Touch了滑动一点距离后,up时触发。
  void onLongPress(MotionEvent e)
  解释:Touch了不移动一直Touch down时触发
  boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,float distanceY)
  解释:Touch了滑动时触发。
  void onShowPress(MotionEvent e)
  解释:Touch了还没有滑动时触发
  (与onDown,onLongPress比较
  onDown只要Touch down一定立刻触发。
  而Touchdown后过一会没有滑动先触发onShowPress再是onLongPress。
  所以Touchdown后一直不滑动,onDown->onShowPress->onLongPress这个顺序触发。
  )
  boolean onSingleTapConfirmed(MotionEvent e)
  boolean onSingleTapUp(MotionEvent e)
  解释:上面这两个函数都是在touchdown后又没有滑动(onScroll),又没有长按(onLongPress),然后Touchup时触发。
  点击一下非常快的(不滑动)Touchup:
  onDown->onSingleTapUp->onSingleTapConfirmed
  点击一下稍微慢点的(不滑动)Touchup:
  onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed 


publicclassGestureActivityextendsActivityimplementsOnTouchListener,
    OnGestureListener {
  GestureDetector detector;
  publicGestureActivity(){
    detector = new GestureDetector(this);
  }
  publicvoidonCreate(BundlesavedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.main); 
      TextView tv = (TextView) findViewById(R.id.TextView001);
      //设置tv的监听器 
      tv.setOnTouchListener(this); 
      tv.setFocusable(true);
      //必须,view才能够处理不同于Tap(轻触)的hold
      tv.setClickable(true); 
      tv.setLongClickable(true); 
      detector.setIsLongpressEnabled(true); 
  } 
  publicbooleanonTouch(View v,MotionEvent event) { 
    returndetector.onTouchEvent(event); 
  } 
  // 用户轻触触摸屏,由1个MotionEventACTION_DOWN触发 
  publicbooleanonDown(MotionEventarg0) { 
    Log.i("MyGesture","onDown"); 
    Toast.makeText(this, "onDown",Toast.LENGTH_SHORT).show(); 
    returntrue; 
  } 
  publicvoidonShowPress(MotionEvent e) { 
    Log.i("MyGesture","onShowPress"); 
    Toast.makeText(this, "onShowPress",Toast.LENGTH_SHORT).show(); 
  } 
  // 用户(轻触触摸屏后)松开,由一个1个MotionEventACTION_UP触发 
  publicbooleanonSingleTapUp(MotionEvent e) { 
    Log.i("MyGesture","onSingleTapUp"); 
    Toast.makeText(this, "onSingleTapUp",Toast.LENGTH_SHORT).show(); 
    returntrue; 
  } 
  // 用户按下触摸屏、快速移动后松开,由1个MotionEventACTION_DOWN, 多个ACTION_MOVE, 1个ACTION_UP触发 
  publicbooleanonFling(MotionEvente1, MotionEvent e2, float velocityX, float velocityY) { 
    Log.i("MyGesture","onFling"); 
    // 参数解释: 
    // e1:第1个ACTION_DOWNMotionEvent 
    // e2:最后一个ACTION_MOVEMotionEvent 
    // velocityX:X轴上的移动速度,像素/秒 
    // velocityY:Y轴上的移动速度,像素/秒 
    // 触发条件 : 
    // X轴的坐标位移大于FLING_MIN_DISTANCE,且移动速度大于FLING_MIN_VELOCITY个像素/秒 
    finalintFLING_MIN_DISTANCE = 100,FLING_MIN_VELOCITY = 200; 
    if (e1.getX() - e2.getX() >FLING_MIN_DISTANCE &&Math.abs(velocityX) > FLING_MIN_VELOCITY){ 
      // Flingleft 
      Log.i("MyGesture","Fling left"); 
      Toast.makeText(this, "FlingLeft",Toast.LENGTH_SHORT).show(); 
    } elseif (e2.getX() - e1.getX() >FLING_MIN_DISTANCE &&Math.abs(velocityX) > FLING_MIN_VELOCITY){ 
      // Flingright 
      Log.i("MyGesture","Fling right"); 
      Toast.makeText(this, "FlingRight",Toast.LENGTH_SHORT).show(); 
    } elseif(e2.getY()-e1.getY()>FLING_MIN_DISTANCE && Math.abs(velocityY)>FLING_MIN_VELOCITY) {
      // Flingdown 
      Log.i("MyGesture","Fling down"); 
      Toast.makeText(this, "Flingdown",Toast.LENGTH_SHORT).show();
    } elseif(e1.getY()-e2.getY()>FLING_MIN_DISTANCE && Math.abs(velocityY)>FLING_MIN_VELOCITY) {
      // Fling up 
      Log.i("MyGesture","Fling up"); 
      Toast.makeText(this, "Flingup",Toast.LENGTH_SHORT).show();
    } 
    returnfalse;
  } 
  // 用户按下触摸屏,并拖动,由1个MotionEventACTION_DOWN, 多个ACTION_MOVE触发 
  publicbooleanonScroll(MotionEvente1, MotionEvent e2, float distanceX, float distanceY) { 
    Log.i("MyGesture","onScroll"); 
    Toast.makeText(this, "onScroll",Toast.LENGTH_LONG).show(); 
    returntrue; 
  } 
  // 用户长按触摸屏,由多个MotionEventACTION_DOWN触发 
  publicvoidonLongPress(MotionEvent e) { 
    Log.i("MyGesture","onLongPress"); 
    Toast.makeText(this, "onLongPress",Toast.LENGTH_LONG).show(); 
  } 
}

  2)在view的新建一个GestureDetector的对象。

  构造函数里

  gestureDetector = new GestureDetector(newHahaGestureDetectorListener());

  然后在View的onTouchEvent里以下这样用,就可以在刚才1)弄的事件里写自己的代码了。


  @Override
  public boolean onTouchEvent(MotionEvent event) {
  gestureDetector.onTouchEvent(event);
  }
  mTouchListener = new OnTouchListener() {
   @Override
   public boolean onTouch(View v, MotionEvent event) {
   // TODO Auto-generated method stub
   float x =event.getXPrecision()*event.getX()+event.getX();
   float y =event.getYPrecision()*event.getY()+event.getY();
   switch (event.getAction()) {
   case MotionEvent.ACTION_DOWN:
   break;
   case MotionEvent.ACTION_MOVE:
   mTouchTimes++;
   if (mTouchTimes > TOUCH_TIMES) {
  // 根据方向计算角度
   if (mCurrentOrientation==DeviceOrientation.Landscape) {
   mAngle = Math.toDegrees(Math.atan2(y - 480 / 2, x))+90;
   } else {
   mAngle = -Math.toDegrees(Math.atan2(y - 480 / 2,320-x))+90;
   }
   Log.w("angle", "mangle:"+mAngle);
   }
   break;
   case MotionEvent.ACTION_UP:
   if (mTouchTimes > TOUCH_TIMES) {
   } else {
   }
   mTouchTimes = 0;
   break;
   default:
   break;
  }
   return true;
   }
   };
  mView.setOnTouchListener(mTouchListener);
 

通过此文,希望能帮助开发Android应用使用触摸事件的朋友,谢谢大家对本站的支持!

您可能感兴趣的文章:Android触摸事件如何实现笔触画布详解Android中View位置和触摸事件详解Android触摸事件传递机制Android在Fragment中实现监听触摸事件Android触摸事件传递机制初识Android触摸事件的应用详解Android触摸事件传递图解Android 触摸事件监听(Activity层,ViewGroup层,View层)详细介绍android中处理各种触摸事件的方法浅谈Android触摸事件和mousedown、mouseup、click事件之间的关系


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯