lulu666 lulu666 - 2 months ago 35
Android Question

MotionEvent.ACTION_UP event is fired twice with seekbar

The onStopTrackingTouch event is fired twice and that's a problem cause I just need to make a getRequest. Here is my code:

VerticalSeekbar.java

public boolean onTouchEvent(MotionEvent event) {

if (!isEnabled()) {
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
super.onTouchEvent(event);
int progress = getMax() - (int) (getMax() * event.getY() / getHeight());
// Ensure progress stays within boundaries
if(progress < 0) {progress = 0;}
if(progress > getMax()) {
progress = getMax();}
setProgress(progress); // Draw progress
if(progress != lastProgress) {
// Only enact listener if the progress has actually changed
lastProgress = progress;
Information.onSeekBarChangeListener.onProgressChanged(this, progress, true);
}
onSizeChanged(getWidth(), getHeight() , 0, 0);
Log.i("radio", "action move");
setPressed(true);
setSelected(true);
case MotionEvent.ACTION_UP:
Log.i("radio", "action up"); //printed twice
Information.onSeekBarChangeListener.onStopTrackingTouch(this);
break;
case MotionEvent.ACTION_CANCEL:
break;
}
return true;
}


Information.java

onSeekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser){
radio = (progress / (double) 10);
tv_radio.setText(radio + " Km");
}

@Override
public void onStartTrackingTouch(SeekBar seekBar){
Log.i("vertical", "onStart");
}

@Override
public void onStopTrackingTouch(SeekBar seekBar){
Log.i("vertical", "onStopTracking"); //printed twice
getRequest request = new getRequest();
request.execute("http://...");
}
};
sb_radio.setOnSeekBarChangeListener(onSeekBarChangeListener);


Any idea why
MotionEvent.ACTION_UP
is detected twice? Even if I just do a simple click in the
Seekbar
without dragging.

Answer

TouchListener will be called for every MotionEvent.ACTION_DOWN, MotionEvent.ACTION_UP, and MotionEvent.ACTION_MOVE

so the problem is, There is a break statement is missing after MotionEvent.ACTION_MOVE so even when you fall under MotionEvent.ACTION_MOVE case the control will keeps on executing the further case until some stop point reached, like break etc

   switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_MOVE:
            super.onTouchEvent(event);
            int progress = getMax() - (int) (getMax() * event.getY() / getHeight());
            // Ensure progress stays within boundaries
            if(progress < 0) {progress = 0;}
            if(progress > getMax()) {
                progress = getMax();}
            setProgress(progress);  // Draw progress
            if(progress != lastProgress) {
                // Only enact listener if the progress has actually changed
                lastProgress = progress;
                Information.onSeekBarChangeListener.onProgressChanged(this, progress, true);
            }
            onSizeChanged(getWidth(), getHeight() , 0, 0);
            Log.i("radio", "action move");
            setPressed(true);
            setSelected(true);
            break; // add a break statement here and problem solved
        case MotionEvent.ACTION_UP:
            Log.i("radio", "action up"); //printed twice
            Information.onSeekBarChangeListener.onStopTrackingTouch(this);
            break;
        case MotionEvent.ACTION_CANCEL:
            break;
    }
    return true;
}