Wednesday, September 2, 2009

Auto-repeat Buttons in Android

To my surprise there doesn't seem to be an attribute with the standard android.View.Button class to make it auto-repeat while the Button is pressed. I've seen this behaviour in the DatePicker dialog, so assumed the behaviour is standard. Well, unless I'm going blind and just missed it, I went and wrote my own AutoRepearButton class.

For the Android fans out there, here is the source:


package com.spleenware;

import java.util.TimerTask;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.Button;

/**
* Surprisingly, an AutoRepeatButton doesn't seem to be in the standard Android View frameworks.
* So, simple implementation here. When Button is held down its onClickListener is called on a timer.
*
* @author Scott Powell
*/
public class AutoRepeatButton extends Button
{
public AutoRepeatButton(Context c)
{
super(c);
}

/**
* Constructor used when inflating from layout XML
*/
public AutoRepeatButton(Context c, AttributeSet attrs)
{
super(c, attrs);
}

/**
* TODO: These could be made variable, and/or set from the XML (ie. AttributeSet)
*/
private static final int INITIAL_DELAY = 900;
private static final int REPEAT_INTERVAL = 100;

private TimerTask mTask = new TimerTask()
{
@Override
public void run()
{
if (isPressed())
{
performClick(); // simulate a 'click'
postDelayed(this, REPEAT_INTERVAL); // rinse and repeat...
}
}
};

@Override
public boolean onTouchEvent(MotionEvent event)
{
if (event.getAction() == MotionEvent.ACTION_DOWN)
postDelayed(mTask, INITIAL_DELAY);
else if (event.getAction() == MotionEvent.ACTION_UP)
removeCallbacks(mTask); // don't want the pending TimerTask to run now that Button is released!

return super.onTouchEvent(event);
}

}

2 comments:

  1. Hey, worked like a charm. Many thanks! (I learned a lot from examining this code).

    ReplyDelete
  2. Used it almost blindly, and worked great at first try... thanks!

    ReplyDelete