【问题标题】:Android onClick blocking onFlingAndroid onClick 阻塞 onFling
【发布时间】:2010-11-22 18:47:45
【问题描述】:

我有一个 Activity,它实现了一个手势检测器来捕捉用户的输入,以便导航到其他屏幕。那工作得很好 - 但是 - 我最近更新了一个派生自 BaseActivity 的类以添加一个 onClick 函数,现在单击事件似乎阻止了 onFling 被击中。 onClick 绑定到我屏幕上的 TextView 区域(在 LinearLayout 中)。 resultsClick 方法使用 XML 布局中的 onClick 属性连接到 TextView。

我尝试更改 onSingleTapUp 和 onDown 中的返回值,但没有成功。我也尝试将日志语句添加到下面的所有函数中。当我在 TextView 区域中滑动时,它们都不会触发,但它们会在屏幕的其他区域触发。

也许我使用了错误的搜索词,但我似乎找不到解决这个问题的示例 - 但我确信这个问题之前已经解决了。

public class DerivedActivity extends BaseActivity
{
   ...
   /**
    * resultsClick - The user clicked on the Results area
    * @param v
    */
   public void resultsClick(View v)
   {
      try
      {
         Log.i(this.toString(), "resultsClick");
         startActivity(new Intent(this, Results_TabHost.class ));
      }
      catch (Exception e)
      {
         Log.e(this.toString(), "Exception" + e.toString());
      }

   }// end resultsClick
   ...
}

这里是实现 GestureListener 代码的基类

public class BaseActivity extends    ActivityGroup 
                          implements OnGestureListener
{
   ...
   private static final int SWIPE_MIN_DISTANCE = 120;
   private static final int SWIPE_MAX_OFF_PATH = 250;
   private static final int SWIPE_THRESHOLD_VELOCITY = 200;

   public boolean onFling(MotionEvent e1, 
                          MotionEvent e2, 
                          float velocityX, 
                          float velocityY)
   {
      try
      {
         Log.i(this.toString(), "onFling");

         // jump right out if not a swipe/fling
         if (Math.abs( e1.getY() - e2.getY() ) > SWIPE_MAX_OFF_PATH)
         {
            return false;
         }

         // right to left swipe
         if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && 
             Math.abs(velocityX)   > SWIPE_THRESHOLD_VELOCITY )
         {
            Log.i(this.toString(), "fling left");
            rightArrowClick(null);

         }
         else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && 
                  Math.abs(velocityX)   > SWIPE_THRESHOLD_VELOCITY )
         {
            Log.i(this.toString(), "fling right");
            leftArrowClick(null);
         }
      }
      catch (Exception e)
      {
         Log.e(this.toString(), "Exception" + e.toString());
      }

      return true;

   }// end onFling

   // These next methods we are required to have - even if unused - 
   // in order for the Gesture Handling to work

   @Override
   public boolean onTouchEvent(MotionEvent motionEvent)
   {
      return this.gestureDetector.onTouchEvent(motionEvent);
   }

   @Override
   public void onLongPress(MotionEvent e)
   {
      // Intentionally not handling - must be overridden by listener class
   }

   @Override
   public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
   {
      // Intentionally not handling - must be overridden by listener class
      // Intentionally returning true - per code examples
      return true;
   }

   @Override
   public void onShowPress(MotionEvent e)
   {
      // Intentionally not handling - must be overridden by listener class
   }

   @Override
   public boolean onSingleTapUp(MotionEvent e)
   {
      // Intentionally not handling - must be overridden by listener class
      // Intentionally returning true - per code examples
      return true;
   }

   @Override
   public boolean onDown(MotionEvent e)
   {
      // Intentionally not handling - must be overridden by listener class
      // Intentionally returning true - per code examples
      return true;
   }
...
}

【问题讨论】:

    标签: android android-activity onclick gesture-recognition


    【解决方案1】:

    您的 onTouchEvent 实现不正确。 您只需返回gestureDector 的结果值。

    如果你的手势检测器没有检测到任何手势,你告诉调用者“我在这里没有什么可做的”,触摸事件将永远不会被发送到 Activity 的孩子。

    如果您的手势检测器未处理该事件,您需要致电 super.onTouchEvent()

    @Override
    public boolean onTouchEvent(MotionEvent motionEvent)
    {
      if(this.gestureDetector.onTouchEvent(motionEvent))
      {
          return true;
      }
      //no gesture detected, let Activity handle touch event
      return super.onTouchEvent(motionEvent);
    }
    

    【讨论】:

    • @CodeFusionMbile - 谢谢你的建议。我刚刚尝试使用上面的代码更新 onTouchEvent ,但它对我看到的行为没有任何影响。我为每个手势事件添加了一个日志以确保。当我尝试在屏幕上滑动时,我会从结果单击中看到日志,但我没有看到其他任何人被记录。
    【解决方案2】:

    请注意此功能:

    @Override
       public boolean onDown(MotionEvent e)
       {
          // Intentionally not handling - must be overridden by listener class
          // Intentionally returning true - per code examples
          return true;
       }
    

    请将返回值改为false。

    【讨论】:

      【解决方案3】:

      当您的代码没有执行任何操作时,您可以返回 false...它将让运动事件系统自行管理所有内容。 返回 true,当您想停止将事件发送到其他子视图时..

      【讨论】:

        【解决方案4】:
        imageView.setOnTouchListener(new View.OnTouchListener() {
                                                @Override
                                                public boolean onTouch(View v, MotionEvent event) {
                                                    if (mDetector.onTouchEvent(event)) {
                                                        return true;
                                                    }
        
                                                    return HomeScreen.super.onTouchEvent(event);
                                                }
                                            });
        
        public class JGestureDetector extends GestureDetector.SimpleOnGestureListener {
                private static final int SWIPE_MIN_DISTANCE = 120;
                private static final int SWIPE_MAX_OFF_PATH = 250;
                private static final int SWIPE_THRESHOLD_VELOCITY = 200;
        
                private SwipeHandler handler;
        
                public SwipeHandler getHandler() {
                    return handler;
                }
        
                public void setHandler(SwipeHandler handler) {
                    this.handler = handler;
                }
        
                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        
                    if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                        return false;
        
                    // left
                    if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
                            && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
        
                        if (handler != null) {
                            handler.onLeft();
        
                            return true;
                        }
        
                        // right
                    } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
                            && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
        
                        if (handler != null) {
                            handler.onRight();
        
                            return true;
                        }
                    }
        
                    return super.onFling(e1, e2, velocityX, velocityY);
                }
        
                public static abstract class SwipeHandler {
                    public void onLeft() {
                    }
        
                    public void onRight() {
                    }
                }
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-20
          • 2016-07-18
          • 1970-01-01
          • 1970-01-01
          • 2016-07-06
          相关资源
          最近更新 更多