Android onClick блокирует onFling

У меня есть действие, которое реализует детектор жестов, чтобы поймать пользовательский ввод для перехода на другие экраны. Это работало нормально, но недавно я обновил класс, производный от BaseActivity, чтобы добавить функцию onClick, и теперь это событие щелчка, похоже, блокирует попадание onFling. OnClick привязан к области TextView (в LinearLayout), которая есть у меня на экране. Метод resultsClick связан с TextView с помощью его свойства onClick в макете XML.

Я безуспешно пытался изменить возвращаемые значения в 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;
   }
...
}

person bursk    schedule 22.11.2010    source источник


Ответы (3)


Ваша реализация onTouchEvent неверна. Вы просто возвращаете значение результатаgestDector.

Однако, если ваш детектор жестов не обнаруживает никаких жестов, вы говорите вызывающему абоненту: «Мне здесь нечего делать», и событие касания никогда не будет отправлено дочерним элементам действия.

Вам нужно вызвать 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);
}
person CodeFusionMobile    schedule 22.11.2010
comment
@CodeFusionMbile - спасибо за ваше предложение. Я только что попытался обновить onTouchEvent, используя приведенный выше код, но это не повлияло на поведение, которое я вижу. Я добавил журнал к каждому из событий жеста, чтобы убедиться. Когда я пытаюсь провести пальцем по экрану, я вижу журнал результатов, но я не вижу, чтобы кто-либо из других регистрировался. - person bursk; 23.11.2010

Пожалуйста, обратите внимание на эту функцию:

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

Пожалуйста, измените возвращаемое значение на false.

person user1145055    schedule 23.03.2012

Вы можете просто вернуть false, когда ваш код ничего не делает... Это позволит системе событий движения управлять всем самостоятельно. Верните true, если вы хотите остановить отправку события другому дочернему представлению.

person oberthelot    schedule 02.05.2011