Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android onClick blocking onFling

I have an Activity that implements a Gesture Detector to catch the user fling input for navigation to other screens. That was working fine - but - I recently updated a class that derives from BaseActivity to add an onClick function and now that click event seems to block the onFling from being hit. The onClick is tied to a TextView area (in a LinearLayout) I have on my screen. The resultsClick method is wired to the TextView using its onClick property in the XML layout.

I've tried changing the return values in onSingleTapUp and onDown without luck. I've also tried adding log statements to all the functions below as well. None of them fire when I fling in the TextView area but they do on other areas of the screen.

Maybe I am using the wrong search terms, but I couldn't seem to find an example that addressed this - yet I'm sure this problem has been solved before.

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
   ...
}

Here is the base class that implements the GestureListener code

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;
   }
...
}
like image 786
bursk Avatar asked Nov 22 '10 18:11

bursk


3 Answers

Your implementation of onTouchEvent is incorrect. You simply return the value of the gestureDector's result.

If your gesture detector doesn't detect any gestures however, you tell the caller "I didn't have anything to do here" and the touch event will never be sent down to the Activity's children.

You need to call super.onTouchEvent() if your gesture detector didn't handle the event.

@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);
}
like image 100
CodeFusionMobile Avatar answered Sep 19 '22 03:09

CodeFusionMobile


Please give attention to this function:

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

Please change the return value to false.

like image 4
user1145055 Avatar answered Sep 23 '22 03:09

user1145055


You can just return false, when nothing is done by your code...It will let the motion event system manage everything on it's own. Return true, when you wanna stop the event to be dispatched to other childs view..

like image 1
oberthelot Avatar answered Sep 21 '22 03:09

oberthelot