Просмотр с помощью прослушивателя жестов и onLongClickListener

Я пытаюсь реализовать представление, в котором есть как longClickListener, так и детектор жестов. По сути, мне нужна кнопка для отображения представления, когда пользователь долго нажимает на первое представление, а затем я хочу обнаружить движение вверх. Я хотел бы сделать так, чтобы пользователю вообще не приходилось поднимать палец и нажимать как на долгое нажатие, так и на бросковое движение.

Вот мой код для longClickListener:

flipCard.setOnLongClickListener(new View.OnLongClickListener() {
           public boolean onLongClick(View view) {
                    answerRight.setVisibility(View.VISIBLE);
                    answerRight.startAnimation(AnimationUtils.loadAnimation(view.getContext(), R.anim.grow_from_middle));
                    answerWrong.setVisibility(View.VISIBLE);
                    answerWrong.startAnimation(AnimationUtils.loadAnimation(view.getContext(), R.anim.grow_from_middle));
                    return false;
           }
        });  

Вот код моего жестового декоратора:

gestureDetectorScore = new GestureDetector(new ScoreGestureDetector());
    gestureListenerScore = new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
            if (gestureDetectorScore.onTouchEvent(event)) {
                return true;
            }
            return false;
        }
    };
private class ScoreGestureDetector extends SimpleOnGestureListener {

    private static final int SWIPE_MIN_DISTANCE = 5;
    private static final int SWIPE_THRESHOLD_VELOCITY = 2;

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
         try {
              //if (Math.abs(e1.getX() - e2.getX()) > SWIPE_MAX_OFF_PATH)
                 //return false;
              // right to left swipe
              //if(e1.getY() - e2.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
              if(e1.getY() - e2.getY() > SWIPE_MIN_DISTANCE){ 
                 Toast.makeText(AndroidOrientationSensor.this, "Up Swipe", Toast.LENGTH_SHORT).show();
              }  
              //else if (e2.getY() - e1.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
              else if (e2.getY() - e1.getY() > SWIPE_MIN_DISTANCE){
                   Toast.makeText(AndroidOrientationSensor.this, "Down Swipe", Toast.LENGTH_SHORT).show();
              }
            } catch (Exception e) {
                // nothing
            }
            return false;
    }

    @Override
    public boolean onDown(MotionEvent e1){
        Toast.makeText(AndroidOrientationSensor.this, "Up Swipe", Toast.LENGTH_SHORT).show();
        return true;
    }

}

Наконец, я устанавливаю указатель жестов в представление «флипкарта» следующим образом:

flipCard.setOnTouchListener(gestureListenerScore);

Любая помощь будет принята с благодарностью.


person Jon Lange    schedule 09.03.2011    source источник


Ответы (3)


Я думаю, что проблема, с которой вы столкнетесь, заключается в том, что событие касания потребляется кнопкой, тогда второе представление его не получит.

Даже если бы это было так, бросок, как я полагаю, будет вызван только тогда, когда пользователь выполнит бросок от начала до конца.

Единственное, что я могу придумать (несмотря на то, что это очень ужасно / взломано), - это попытаться вставить фальшивое событие касания. Это может позволить пользователю выполнить бросок, но это тоже не особенно стабильно.

Лучшим способом справиться с этим было бы, чтобы группа представлений потребляла события касания, передавала события касания детектору жестов для обнаружения длинного щелчка, затем устанавливала флаг в слушателе касаний групп представлений, чтобы указать, что ожидается бросок, а затем вручную определить, когда предыдущий и текущий y выходят за пределы порогового значения. Это даст вам некоторое представление о скорости, но, вероятно, далеко не так значимо, как скорость, предоставленная в методе обратного вызова onFling.

person Matt Gaunt    schedule 09.03.2011
comment
Хорошая идея, но у меня много проблем с ее реализацией. Я пытаюсь воссоздать longClickEvent в слушателе жестов. Проверив координаты, чтобы убедиться, что они совпадают с кнопкой, а затем смоделировав долгий щелчок, я, возможно, смогу поймать событие бросания. - person Jon Lange; 10.03.2011
comment
К сожалению, поскольку вы хотите, чтобы все это происходило за одно касание, простого способа сделать это не будет. Все, что я могу сказать, это из вашего текущего кода, вместо того, чтобы передавать GestureDetector в setOnTouchListener, вы можете переопределить метод onTouchEvent, а затем вернуться к mGestureDetector.onTouchEvent (motionEvent); очевидно, с этим, после долгого щелчка вы можете сами потреблять Touch Events и делать с ними то, что хотите (то есть обнаруживать пользовательский бросок) - person Matt Gaunt; 10.03.2011

В итоге для решения этой проблемы я поместил gestureDectector в представление и переопределил метод onDown. Это позволило мне смоделировать событие щелчка. Мне не удалось получить одновременно длинный щелчок и событие смахивания, но для моих целей событие щелчка срабатывает во время смахивания, что, похоже, работает достаточно хорошо. Спасибо GauntFace за вдохновение.

person Jon Lange    schedule 15.03.2011

GestureListener также имеет событие onLongPress.

person Marcos Vasconcelos    schedule 15.03.2011
comment
Это правда, но тогда событие потребляется и не улавливает событие бросания. На самом деле это довольно интересно, так как для того, чтобы поймать событие onLongPress, вы должны сначала поймать событие onDown. В api указано, что всем остальным событиям должно предшествовать this. Более того, события onLongPress всегда используют событие, что отменяет событие бросания. см. developer.android.com/ ссылка / android / view / - person Jon Lange; 16.03.2011