OnTouchListener в представлении, которое находится внутри ScrollView - PullRequest
0 голосов
/ 22 января 2019

У меня есть вид, который находится внутри ScrollView.Я хочу вызывать какой-либо метод каждые 80 мсек, пока пользователь удерживает нажатой эту панель просмотра.Вот что я реализовал:

final Runnable vibrate = new Runnable() {
    public void run() {
        vibrate();
    }
};

theView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
            final ScheduledFuture<?> vibrateHandle =
                    scheduler.scheduleAtFixedRate(vibrate, 0, 80, MILLISECONDS);
            vibrateHanlers.add(vibrateHandle);
            return true;
        }
        if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL
                || motionEvent.getAction() == MotionEvent.ACTION_UP) {
            clearAllScheduledFutures();
            return false;
        }
        return true;
    }
});

Проблема в том, что ACTION_CANCEL вызывается для наименьшего движения пальца.Я знаю, что это потому, что View находится внутри ScrollView, но я не уверен, каковы мои варианты здесь.Создаю ли я пользовательский ScrollView и пытаюсь выяснить, касался ли нужный вид, и отключить событие касания для ScrollView?Или, может быть, отключить сенсорное событие для SrollView для небольшого порога перемещения?Или что-то еще?

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Вот как я это исправил.

Я создал пользовательский ScrollView:

public class MainScrollView extends ScrollView {
    private boolean shouldStopInterceptingTouchEvent = false;

    public void setShouldStopInterceptingTouchEvent(boolean shouldStopInterceptingTouchEvent) {
        this.shouldStopInterceptingTouchEvent = shouldStopInterceptingTouchEvent;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (shouldStopInterceptingTouchEvent)
            return false;
        else
            return super.onInterceptTouchEvent(ev);
    }
}

А в onTouchEvent:

theView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
            svMain.setShouldStopInterceptingTouchEvent(true);
            final ScheduledFuture<?> vibrateHandle =
                    scheduler.scheduleAtFixedRate(vibrate, 0, 80, MILLISECONDS);
            vibrateHanlers.add(vibrateHandle);
            return true;
        }
        if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL
                || motionEvent.getAction() == MotionEvent.ACTION_UP) {
            svMain.setShouldStopInterceptingTouchEvent(false);
            clearAllScheduledFutures();
            return false;
        }
        return true;
    }
});

Итак, вместо того, чтобы определять, когда прекратить перехват touchEvent в ScrollView, я решаю, что в onTouchListener из View.

0 голосов
/ 22 января 2019

Не могли бы вы попытаться вернуть true вместо false в событии ActionUp, чтобы событие считалось использованным

if (motionEvent.getAction() == MotionEvent.ACTION_CANCEL
                || motionEvent.getAction() == MotionEvent.ACTION_UP) {
            clearAllScheduledFutures();
            return true;
        }
...