Как получить непрерывное сенсорное событие? - PullRequest
11 голосов
/ 29 марта 2010

Мой класс расширяет View, и мне нужно получать непрерывные события касания.

Если я использую:

public boolean onTouchEvent(MotionEvent me) {

    if(me.getAction()==MotionEvent.ACTION_DOWN) {
        myAction();
    }
    return true;
}

... событие касания регистрируется один раз.

Что делать, если мне нужно непрерывно касаться пальца? Пожалуйста, скажите мне, что мне не нужно использовать потоки или таймеры. Мое приложение уже слишком тяжелое.

Спасибо.

Ответы [ 7 ]

15 голосов
/ 29 марта 2010

Используйте if(me.getAction() == MotionEvent.ACTION_MOVE). Невозможно держать палец на 100% полностью неподвижным на экране, поэтому Action_Move будет вызываться каждый раз, когда палец двигается, даже если это всего лишь один или два пикселя.

Вы также можете прослушивать me.getAction() == MotionEvent.ACTION_UP - пока это не произойдет, пользователь все равно должен держать палец на экране.

5 голосов
/ 06 августа 2013

Вам нужно установить эти свойства для элемента андроид: фокусируемый = «истина» андроид: кликабельны = «истина» если нет, просто выполните действие вниз.

4 голосов
/ 29 марта 2010

Это простой фрагмент кода, который показывает, как вы можете обрабатывать событие продолжения касания. Когда вы дотрагиваетесь до устройства и удерживаете нажатие и перемещаете искатель, выполняется действие «Переместить касание».

@Override
public boolean onTouchEvent(MotionEvent event) {
    float x = event.getX();
    float y = event.getY();
    if(isTsunami){
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            // Write your code to perform an action on down
            break;
        case MotionEvent.ACTION_MOVE:
            // Write your code to perform an action on contineus touch move
            break;
        case MotionEvent.ACTION_UP:
            // Write your code to perform an action on touch up
            break;
    }
    }
    return true;
}
1 голос
/ 11 января 2018

Это может помочь,

requestDisallowInterceptTouchEvent(true);

в родительском представлении, как это -

        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            view.getParent().requestDisallowInterceptTouchEvent(true);
            switch(motionEvent.getAction()){
            }

            return false; 

         }
1 голос
/ 20 июня 2011

Попробуй это. Это работает для меня:

public static OnTouchListener loadContainerOnTouchListener() {
    OnTouchListener listener = new OnTouchListener(){
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        LinearLayout layout = (LinearLayout)v;
        for(int i =0; i< layout.getChildCount(); i++)
        {
            View view = layout.getChildAt(i);
            Rect outRect = new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
            if(outRect.contains((int)event.getX(), (int)event.getY()))
            {
                Log.d(this.getClass().getName(), String.format("Over view.id[%d]", view.getId()));
            }
        }

    }

Помните: установленный слушатель должен быть макетом контейнера (сетка, относительный, линейный)

LinearLayout layout = findViewById(R.id.yourlayoutid);
layout.setOnTouchListener(HelperClass.loadContainerOnTouchListener());
0 голосов
/ 28 ноября 2017

Все эти ответы частично верны, но не решают правильно проблему.

Прежде всего, для всех, кто решил отследить, когда событие ACTION_MOVE. Ну что работает только угадай когда? Когда пользователь двигает пальцем, это можно сделать, если вы решите внедрить пользовательский элемент управления большим пальцем, это нормально, но для обычной пользовательской кнопки это не так.

Во-вторых, использование флага внутри ACTION_DOWN и проверка его в ACTION_UP кажется логичным способом сделать это, но, как Clusterfux выяснит, если вы реализуете while(!up_flag) логику, вы попадаете в проблемы;)

Итак, правильный способ сделать это упоминается здесь:

Непрерывное «Action_DOWN» в Android

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

0 голосов
/ 29 мая 2014

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

float x = 0, y = 0;

@Override
public boolean onTouchEvent(MotionEvent event) {
    x = event.getX();
    y = event.getY();

    // handle touch events with 
    switch( event.getActionMasked() ) {
        case MotionEvent.ACTION_DOWN :
            if(cont)
            {
                // remove any previous callbacks
                removeCallbacks(contin);

                // post new runnable
                postDelayed(contin, 10);
            }
            invalidate();
            return true;
        case MotionEvent.ACTION_MOVE :
            if(!cont && thumbing != null)
            {
                //  do non-continuous operations here
            }
            invalidate();       
            return true;
        case MotionEvent.ACTION_UP :

            // set runnable condition to false
            x = 0;

            // remove the callbacks to the thread
            removeCallbacks(contin);
            invalidate();
            return true;
        default :
            return super.onTouchEvent(event);
    }
}

public boolean cont = false;

// sets input to continuous
public void set_continuous(boolean b) { cont = b; }


public Runnable contin = new Runnable()
{

    @Override
    public void run() {
        if(x != 0)
        {
            //  do continuous operations here
            postDelayed(this, 10);
        }
    }

};

Однако, быстрое примечание, убедитесь, что в вашем основном действии, которое вызывает это представление, вручную удаляются обратные вызовы с помощью метода onPause, как указано ниже

@Override
protected void onPause() {
    if(left.cont) left.removeCallbacks(left.contin);
    if(right.cont) right.removeCallbacks(left.contin); 
    super.onPause();
}

Таким образом, если вы приостанавливаете и возвращаетесь, сенсорные события не обрабатываются дважды, и представление освобождается от издержек потока.

** протестировано на Samsung Galaxy S3 с аппаратным ускорением на **

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...