1
brown = (Button) findViewById(R.id.brownButton);
    brown.setOnTouchListener(new OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                count++;
                Log.d("count", "" + count);
                return true;
            } else if (event.getAction() == (MotionEvent.ACTION_UP)) {
                count--;
                Log.d("count", "" + count);
                return true;

            }
            return false;

        }
    });

When my finger presses and holds the button my count will only increment ONCE. When I let go it will decrement accordingly. Please can someone show me how I can get my code to increment as long as my finger is holding the button down. Thanks.

Shant
  • 185
  • 1
  • 2
  • 10
  • Are you getting any other messages besides `MotionEvent.ACTION_DOWN` or `MotionEvent.ACTION_UP`, like `MotionEvent.ACTION_MOVE` maybe? – Steve Blackwell Dec 01 '11 at 21:27
  • 2
    You won't get an ACTION_MOVE or another touch events unless you move your finger, it sounds like you want to increment a number based on the amount of time passed since the button has be pressed – FunkTheMonk Dec 01 '11 at 23:37
  • I have the exact problem mentioned by Funk. I need to touch and hold, but ACTION_MOVE is not detected unless I lean my finger one way or the other. How would I do a continuous action that stops when ACTION_UP is detected? – clusterflux May 18 '13 at 08:34

2 Answers2

2

A touch listener works like this:

It receives a ACTION_DOWN event (the user touches)

It then receives all the following events (if true is returned) and treats all the following events as ACTION_MOVE events

The touch lisetener keeps receiving ACTION_MOVE events until it receives an ACTION_UP or ACTION_CANCEL event.

So ACTION_DOWN is only triggered once, then any number of ACTION_MOVE events, then either a single ACTION_UP or ACTION_CANCEL.

If you want your counter to increment you need to check for ACTION_MOVE events.

@Override
public boolean onTouch(View v, MotionEvent event) {

    switch(event.getAction()){
    case MotionEvent.ACTION_DOWN:
     //do something on DOWN 
         break;
    case MotionEvent.ACTION_MOVE:
         //do something on MOVE
         break;
    case MotionEvent.ACTION_UP:
     //do something on UP           
         break;
    }
    return true;
}
triggs
  • 5,890
  • 3
  • 32
  • 31
  • I did like you suggested, right after I receive action_down i check for action_move but it still only executes my increment only once. If I misunderstood something please re-explain. Thanks. – Shant Dec 01 '11 at 22:38
  • @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { Log.d("Action Down", "Down"); if (event.getAction() != MotionEvent.ACTION_MOVE) { Log.d("Action Move", "Move"); } } return false; } – Shant Dec 01 '11 at 22:50
  • why != action_move, also you need to return true for it keep registering events – triggs Dec 01 '11 at 22:51
  • sorry about the != i was trying something and copied and pasted that one by mistake. Even when I use == it would not work. So you are saying switch the return false with a return true? – Shant Dec 01 '11 at 23:00
  • yeah change the return statement. – triggs Dec 01 '11 at 23:07
  • Now it looks like this: @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { Log.d("Action Down", "Down"); if (event.getAction() == MotionEvent.ACTION_MOVE) { Log.d("Action Move", "Move"); } } return true; } – Shant Dec 01 '11 at 23:12
  • triggs thanks for helping, i copied the code just like you have it and all i did was add log.d statements instead of do something. If i press and hold the button down it still only executes Down once and when i let go it executed Up once. I still cant get it to do what i want which is to keep executing while the button is down. – Shant Dec 01 '11 at 23:34
  • like i said in my answer only a single down event, the rest become move events until up or cancel – triggs Dec 01 '11 at 23:36
1

I also needed to do this, but this question was never adequately answered, even though it is fairly old. However, a good solution can be found here: android repeat action on pressing and holding a button

I am adapting that solution to this problem. I tested it and it works for me.

Button brown = (Button) findViewById(R.id.brownButton);
brown.setOnTouchListener(new View.OnTouchListener() {

    private Handler mHandler;
    private int count = 0;

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            if (mHandler != null)
                return true;
            mHandler = new Handler();
            mHandler.postDelayed(mAction, 500);
            break;
        case MotionEvent.ACTION_UP:
            if (mHandler == null)
                return true;
            mHandler.removeCallbacks(mAction);
            mHandler = null;
            break;
        }
        return true; // before I had written false
    }

    Runnable mAction = new Runnable() {
        @Override
        public void run() {
            Log.d("count: ", "" + count);
            count++;
            mHandler.postDelayed(this, 500);
        }
    };

});

In the future I will apply this solution to a custom soft keyboard to allow the space and delete keys to continue working when being held down.

Update: Today I finally got around to making the continuous delete key. I thought I had tested my above code before, but today when I was doing it I had to return true from the onTouch method in order to get it to work.

Community
  • 1
  • 1
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
  • I also worth noticing that when you press your finger against a button the function `onTouch()` is entered multiple times, for a while at least. Then it seems (in my experience) that you need to move your finger across the button to cause it to trigger continuously. Perhaps this could be of use to you. – Abdel Aleem Apr 27 '22 at 10:37