Continuously increase integer value as the button is pressed

While the accepted answer is totally correct, it can be simplified a bit.

Basically, we can optimize two things:

  • We don't need the OnTouchListener.
  • We can instantiate the runnable object just once instead of creating multiple objects.

So this is my version:

// global variables
Handler handler = new Handler();
Runnable runnable;

increaseView.setOnLongClickListener(new View.OnLongClickListener() {

    @Override
    public boolean onLongClick(View v) {

        runnable = new Runnable() {
            @Override
            public void run() {
                if (!increaseView.isPressed()) return;
                increaseValue();
                handler.postDelayed(runnable, DELAY);
            }
        };

        handler.postDelayed(runnable, DELAY);
        return true;

    }

});

Here the runnable object is reused. And when the view is not pressed anymore, it will stop calling itself.

The decrease view or button can be defined in a similar way.


For that to work, you need a thread that will update the integer value when you long press on a button.

Create a handler in your activity:

private Handler repeatUpdateHandler = new Handler();

And 2 vars which will state: is it increment or decrement? Only one set at a time.

private boolean mAutoIncrement = false;
private boolean mAutoDecrement = false;

And the present number value

public int mValue;

And a class that will run in another thread:

class RptUpdater implements Runnable {
    public void run() {
        if( mAutoIncrement ){
            increment();
            repeatUpdateHandler.postDelayed( new RptUpdater(), REP_DELAY );
        } else if( mAutoDecrement ){
            decrement();
            repeatUpdateHandler.postDelayed( new RptUpdater(), REP_DELAY );
        }
    }
}

Add a long press listener to your button:

mBTIncrement.setOnLongClickListener( 
            new View.OnLongClickListener(){
                public boolean onLongClick(View arg0) {
                    mAutoIncrement = true;
                    repeatUpdateHandler.post( new RptUpdater() );
                    return false;
                }
            }
    );   

mBTIncrement.setOnTouchListener( new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
            if( (event.getAction()==MotionEvent.ACTION_UP || event.getAction()==MotionEvent.ACTION_CANCEL) 
                    && mAutoIncrement ){
                mAutoIncrement = false;
            }
            return false;
        }
    });  

In the above case the button is the increment one. Create another button which will set mAutoDecrement to true.

And decrement() will be a function, which will set your instance int variable like this:

public void decrement(){
    mValue--;
    _value.setText( ""+mValue );
}

You figure the increment out. Oh and REP_DELAY is a static int variable set to 50.

I see this is an excerpt from Jeffrey Cole's open source NumberPicker available at http://www.technologichron.net/ Proper author's attribution must be added.