当前位置: 移动技术网 > IT编程>移动开发>Android > Android 的触摸事件详解及示例代码

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

2019年07月24日  | 移动技术网IT编程  | 我要评论

嘶吼豺狼皮帽,女子派出所自缢,95580网上银行

由于触摸(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应用使用触摸事件的朋友,谢谢大家对本站的支持!

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网