Reputation: 6676
Hi have a "scrub" or "scan" button on a music player that I'm writing. What I'd like my button to do is jump a number of milliseconds ahead in the tune every couple of second if the user holds the button for a long period of time.
How can I get multiple onLongClick() events to occur if I hold the button? At the moment I only get one and thats it. There must be a way to reset the timer so it happens again surely.. I hope?
Upvotes: 0
Views: 966
Reputation: 17429
As said in the comment, you can listen for onLongClick()
and then stop moving cursor on ACTION_UP
event:
v.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if(KeyEvent.ACTION_UP == event.getAction())
if(isMoving)
{
isMoving = false;
stopMovingCursor();
}
return false;
}
});
v.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
isMoving = true;
startMovingCursor();
return false;
}
});
Upvotes: 1
Reputation: 6676
Here's the solution that I cobbled together thats working well for me. I would have accepted the previous answers but they didn't take into account moving outside of the button's view. I hope the below code helps somebody else out in the same predicament. 90% of this code is not mine - so many thanks to the other stackoverflow posting that provided this.
EDIT: Actually, this is not perfect either - it doesn't animate button touches.
import android.content.Context;
import android.graphics.Rect;
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 = 1000;
private boolean mRepeatStarted = false;
private Runnable repeatClickWhileButtonHeldRunnable = new Runnable()
{
@Override
public void run()
{
// Perform the present
// repetition of the
// click action
// provided by the
// user
// in
// setOnClickListener().
mRepeatStarted = true;
performLongClick();
// Schedule the next
// repetitions of the
// click action, using
// a faster repeat
// interval than the
// initial repeat
// delay interval.
postDelayed( repeatClickWhileButtonHeldRunnable, repeatIntervalInMilliseconds );
}
};
private void commonConstructorCode()
{
mRepeatStarted = false;
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 );
// Schedule the start of repetitions after a one half second delay.
postDelayed( repeatClickWhileButtonHeldRunnable, initialRepeatDelay );
}
else
if( action == MotionEvent.ACTION_UP )
{
// Cancel any repetition in progress.
removeCallbacks( repeatClickWhileButtonHeldRunnable );
if( mRepeatStarted == false )
{
// PDS: I put this here..
performClick();
}
mRepeatStarted = false;
return true;
}
else
if( action == MotionEvent.ACTION_MOVE )
{
int[] l = new int[2];
v.getLocationOnScreen( l );
Rect rect = new Rect( l[0], l[1], l[0] + v.getWidth(), l[1] + v.getHeight() );
if( ! rect.contains( v.getLeft() + (int) event.getX(),
v.getTop() + (int) event.getY()))
{
// User moved outside bounds
removeCallbacks( repeatClickWhileButtonHeldRunnable );
mRepeatStarted = false;
}
}
else
if( action == MotionEvent.ACTION_CANCEL )
{
removeCallbacks( repeatClickWhileButtonHeldRunnable );
mRepeatStarted = false;
}
// 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: 0
Reputation: 10977
Start a Timer on onLongClick()
that executes your jump action every second or two. Stop the Timer when you get the ACTION_UP
keyEvent.
Upvotes: 1