stevendesu
stevendesu

Reputation: 16841

How to handle SeekBar change on Android TV?

I have an app with a SeekBar. In order to detect when a user performs a seek on a phone, I do the following:

        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged ( SeekBar seekBar, int progress, boolean fromUser )
            {
                // Do nothing?
            }

            @Override
            public void onStartTrackingTouch ( SeekBar seekBar )
            {
                // TODO: Do we need to handle this in any way? (perhaps stop the updateProgress event?)
            }

            @Override
            public void onStopTrackingTouch ( SeekBar seekBar )
            {
                if (!seekingEnabled)
                    return;

                // Handle seek
                player.seekTo(seekBar.getProgress());
            }
        });

When I load the app in Android TV and use the D-pad to manipulate the seek bar, I notice the onProgressChanged event gets thrown each time I scroll left or right, but there doesn't seem to be any event fired when a user then presses the D-pad center button ("locking in" the seek, as they would if they released their finger)

How can I register a listener to the D-pad center button so facilitate a smooth seeking experience on Android TV?

Upvotes: 0

Views: 1267

Answers (1)

Asttoxa
Asttoxa

Reputation: 26

I made this, and it works.

public class TvSeekBar extends AppCompatSeekBar implements SeekBar.OnSeekBarChangeListener  {

    interface TvSeekBarListener{
        void onStartPreview(TvSeekBar tvSeekBar, int progress);
        void onStopPreview(TvSeekBar tvSeekBar, int progress);
        void onProgressChanged(TvSeekBar tvSeekBar, int progress, boolean fromUser);
    }

    private TvSeekBarListener listener = null;

    public TvSeekBar(Context context) {
        this(context, null, 0);
    }

    public TvSeekBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TvSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        super.setOnSeekBarChangeListener(this);
    }


    public void setListener(TvSeekBarListener l){
        listener = l;
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        if(listener != null)
            listener.onProgressChanged(this, progress,fromUser);
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        if(listener != null)
            listener.onStartPreview(this, getProgress());
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        if(listener != null)
            listener.onStopPreview(this,  getProgress());
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        onStartTrackingTouch(this);
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
        onStopTrackingTouch(this);
        return super.onKeyUp(keyCode, event);
    }
}

if you want set filter on key Dpad (for example only left or right) add:

   @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if(keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT)
        onStartTrackingTouch(this);
    return super.onKeyDown(keyCode, event);
}

Upvotes: 1

Related Questions