Reputation: 6012
I have a Two buttons PLUS and MINUS along with and editText called T. If the user clicks on PLUS, The editText value should increase, and if the user presses MINUS, the value should decrease. Now, if the user HOLDS the button for a long time, I want to do the same thing again and again.It would be better if the task became accelerated. eg.
The user holds the button, for 1 sec, the rate of change of T is 1/sec. If he continues holding it for some more time, the rate of change of T is , say 4.
How do I go about this ?
Upvotes: 2
Views: 571
Reputation: 6012
I have posted a perfect, working solution:
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
public class AutoRepeatButton extends Button {
private long initialRepeatDelay = 500;
private long repeatIntervalInMilliseconds = 100;
// speedup
private long repeatIntervalCurrent = repeatIntervalInMilliseconds;
private long repeatIntervalStep = 2;
private long repeatIntervalMin = 10;
private Runnable repeatClickWhileButtonHeldRunnable = new Runnable() {
@Override
public void run() {
// Perform the present repetition of the click action provided by the user
// in setOnClickListener().
performClick();
// Schedule the next repetitions of the click action,
// faster and faster until it reaches repeaterIntervalMin
if (repeatIntervalCurrent > repeatIntervalMin)
repeatIntervalCurrent = repeatIntervalCurrent - repeatIntervalStep;
postDelayed(repeatClickWhileButtonHeldRunnable, repeatIntervalCurrent);
}
};
private void commonConstructorCode() {
this.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
// Just to be sure that we removed all callbacks,
// which should have occurred in the ACTION_UP
removeCallbacks(repeatClickWhileButtonHeldRunnable);
// Perform the default click action.
performClick();
// Schedule the start of repetitions after a one half second delay.
repeatIntervalCurrent = repeatIntervalInMilliseconds;
postDelayed(repeatClickWhileButtonHeldRunnable, initialRepeatDelay);
} else if (action == MotionEvent.ACTION_UP) {
// Cancel any repetition in progress.
removeCallbacks(repeatClickWhileButtonHeldRunnable);
}
// Returning true here prevents performClick() from getting called
// in the usual manner, which would be redundant, given that we are
// already calling it above.
return true;
}
});
}
public AutoRepeatButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
commonConstructorCode();
}
public AutoRepeatButton(Context context, AttributeSet attrs) {
super(context, attrs);
commonConstructorCode();
}
public AutoRepeatButton(Context context) {
super(context);
commonConstructorCode();
}
}
Upvotes: 1
Reputation: 93569
You override onTouchEvent
and when you see a touch down you set a timer for 1s and change the value of the text by 1. When the timer goes off, you change the value of the text by 1 and set the next timer.
If its time to speed things up, you make the timer faster. When you finally see an ACTION_UP
in onTouchEvent
you cancel the last timer.
Upvotes: 2