您的位置:首页 > 其它

解决GridView的长按事件在手机上执行而在平板电脑上先执行Down在之后才和down事件一样传递给最终的目标view的onTouchEvent()处理

2015-12-14 17:24 453 查看
问题:一个Gridiew的拖拽应用 在模拟器上 运行的没有一点问题 
当我部署到平板电脑上 长按事件 不起作用了 
研究: 

Java代码 

 





public boolean onInterceptTouchEvent(MotionEvent ev) {
  

        //这时候 你得到的x,y是在DragLayer下面得到的 这时候 容器 就是DragLayer了   

        int x = (int)ev.getX();
  

        int y = (int)ev.getY();
  

           

        switch(ev.getAction()){
  

            case MotionEvent.ACTION_DOWN:
  

                System.out.println("onInterceptTouchEvent down");
  

                return false;
  

            case MotionEvent.ACTION_MOVE:
  

                System.out.println("onInterceptTouchEvent move");
  

                return ture;
  

            case MotionEvent.ACTION_UP:
  

                System.out.println("onInterceptTouchEvent up");
  

                System.out.println(111);
  

                return false;
  

        }   

        return super.onInterceptTouchEvent(ev);
  

    }  

[java] view
plaincopy

public boolean onInterceptTouchEvent(MotionEvent ev) {  

        //这时候 你得到的x,y是在DragLayer下面得到的 这时候 容器 就是DragLayer了  

        int x = (int)ev.getX();  

        int y = (int)ev.getY();  

          

        switch(ev.getAction()){  

            case MotionEvent.ACTION_DOWN:  

                System.out.println("onInterceptTouchEvent down");  

                return false;  

            case MotionEvent.ACTION_MOVE:  

                System.out.println("onInterceptTouchEvent move");  

                return ture;  

            case MotionEvent.ACTION_UP:  

                System.out.println("onInterceptTouchEvent up");  

                System.out.println(111);  

                return false;  

        }  

        return super.onInterceptTouchEvent(ev);  

    }  

我的Gridview的父类的onInterceptTouchEvent 是这样写的 

在模拟器是没有问题的 
我就想down up 我都向下传 但是move我会截获 进行一些操作 

但是 在平板上 就出现问题了 
onItemLongClick事件 根本就没有执行 

后来 调试的时候 我发现 
在平板电脑上长按时 down总是伴随着move 

也就是说 onItemLongClick没有执行的原因就是这个move事件 里面我是return true的 

解决: 

1、建一个静态变量 
   //是否可以移动 
   

Java代码 

 





public static boolean isMove = false;  

[java] view
plaincopy

public static boolean isMove = false;  

2、修改onInterceptTouchEvent 

Java代码 

 





public boolean onInterceptTouchEvent(MotionEvent ev) {
  

        //这时候 你得到的x,y是在DragLayer下面得到的 这时候 容器 就是DragLayer了   

        int x = (int)ev.getX();
  

        int y = (int)ev.getY();
  

           

        switch(ev.getAction()){
  

            case MotionEvent.ACTION_DOWN:
  

                System.out.println("onInterceptTouchEvent down");
  

                return false;
  

            case MotionEvent.ACTION_MOVE:
  

                System.out.println("onInterceptTouchEvent move");
  

                break;
  

            case MotionEvent.ACTION_UP:
  

                System.out.println("onInterceptTouchEvent up");
  

                System.out.println(111);
  

                return false;
  

        }   

        return StaticConstant.isMove;
  

    }  

[java] view
plaincopy

public boolean onInterceptTouchEvent(MotionEvent ev) {  

        //这时候 你得到的x,y是在DragLayer下面得到的 这时候 容器 就是DragLayer了  

        int x = (int)ev.getX();  

        int y = (int)ev.getY();  

          

        switch(ev.getAction()){  

            case MotionEvent.ACTION_DOWN:  

                System.out.println("onInterceptTouchEvent down");  

                return false;  

            case MotionEvent.ACTION_MOVE:  

                System.out.println("onInterceptTouchEvent move");  

                break;  

            case MotionEvent.ACTION_UP:  

                System.out.println("onInterceptTouchEvent up");  

                System.out.println(111);  

                return false;  

        }  

        return StaticConstant.isMove;  

    }  

3、在onItemLongClick里面改变isMove的值 

Java代码 

 





StaticConstant.isMove = true;  

[java] view
plaincopy

StaticConstant.isMove = true;  

4、在onTouchEvent up时改过来 

Java代码 

 





StaticConstant.isMove = false;  

[java] view
plaincopy

StaticConstant.isMove = false;  

结论: 

GridVie onItemLongClick 

按理说 只会触发 down 

但是 在平板电脑中 当你触摸时 不可避免的会有move事件的 

那么 为什么是 down move 后再onItemLongClick呢? 

如果该ViewGroup的onInterceptTouchEvent()在接收到down事件处理完成之后return false,那么后续的move, up等事件将继续会先传递给该ViewGroup,之后才和down事件一样传递给最终的目标view的onTouchEvent()处理。 

注意 是之后和down一起传递下去 

因为move紧跟着就发生了 所以 会和down一起传递给子view 

所以 顺序是 down move move..... onItemLongClick 

经测试 结论如下: 

在平板电脑上: 

onItemLongClick事件: down move LongClick up 

onItemClick事件: down move up click 

在模拟器上: 

onItemLongClick事件: down  LongClick up 

onItemClick事件: down  up click 

二. GridView的长按事件与短按事件的区别

1,Android Gridview中按键事件的处理有三个方法  

  public boolean onKeyDown(int keyCode, KeyEvent event)

  public boolean onKeyUp(int keyCode, KeyEvent event)

  public boolean onKeyLongPress(int keyCode, KeyEvent event)

  很明显,长按事件是放到 onKeyLongPress 函数中来处理的。

GridView如果长按时,默认会先相应短按事件(GridView.setOnItemClickListener())的,而长按键事件的处理不应该放到(GridView.setOnLongClickListener())中,而应该放到 onKeyLongPress 函数中来处理,这样才能做到长按短按就能分开,如果一开始长按就相应长按,短按就相应短按,两者不会乱掉或者说干扰。

  具体请看如下步骤:

  第一步,先在 onKeyDown 函数中判断 event.getRepeatCount 的次数(实际上长按就是由一系列的onKeyDown事件触发的)

  @Override

  public boolean onKeyDown(int keyCode, KeyEvent event) {

             。。。。。。

   

     

       

       if (event.getRepeatCount() == 0) {

               event.startTracking();

               return true;

       }

    return super.onKeyDown(keyCode, event);

  }

  如果一直按着不放,可以通过Log 查看onKeyDown 的event.getRepeatCount() 数目变化

  

  

  第二步,重载 onKeyLongPressed 函数,在这个函数中你可以添加你的长按键事件的处理

  @Override

  public boolean onKeyLongPress(int keyCode, KeyEvent event) {  

            

                   lockLongPressKey = true;

                   长按键事件的处理部分;

                   return true;

              

         return super.onKeyLongPress(keyCode, event);

  }

  第三步,如果在onKeyUp 函数中也处理了相同的按键的话,那么需要对 onKeyLongPress 和 onKeyUp 中该按键的处理作互斥处理了

  

  public boolean onKeyUp(int keyCode, KeyEvent event) {        

         if(lockLongPressKey){

                lockLongPressKey = false;

                return true;

           }

    

          return super.onKeyUp(keyCode, event);

  }

  互斥处理的原因是,长按事件处理完后,松开按键后就会执行 onKeyUp 函数。而这两处针对相同的按键想要实现的功能又不一样

  固在此添加一个 private boolean lockLongPressKey = false; 变量,在 onKeyLongPress 函数中处理过以后,在 onKeyUp中便不再处理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: