Skip to content

Instantly share code, notes, and snippets.

@yqritc
Last active April 17, 2024 08:26
Show Gist options
  • Save yqritc/7b5c786930dfb9b47e7a to your computer and use it in GitHub Desktop.
Save yqritc/7b5c786930dfb9b47e7a to your computer and use it in GitHub Desktop.
SeekBar showing its progress as text on thumb

TextThumbSeekBar

Define a custom class extending SeekBar to show the progress text on thumb of SeekBar.

public class TextThumbSeekBar extends SeekBar {

    private int mThumbSize;
    private TextPaint mTextPaint;

    public TextThumbSeekBar(Context context) {
        this(context, null);
    }

    public TextThumbSeekBar(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.seekBarStyle);
    }

    public TextThumbSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        
        mThumbSize = getResources().getDimensionPixelSize(R.dimen.thumb_size);
        
        mTextPaint = new TextPaint();
        mTextPaint.setColor(Color.WHITE);
        mTextPaint.setTextSize(getResources().getDimensionPixelSize(R.dimen.thumb_text_size));
        mTextPaint.setTypeface(Typeface.DEFAULT_BOLD);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
    }

    @Override
    protected synchronized void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        String progressText = String.valueOf(getProgress());
        Rect bounds = new Rect();
        mTextPaint.getTextBounds(progressText, 0, progressText.length(), bounds);

        int leftPadding = getPaddingLeft() - getThumbOffset();
        int rightPadding = getPaddingRight() - getThumbOffset();
        int width = getWidth() - leftPadding - rightPadding;
        float progressRatio = (float) getProgress() / getMax();
        float thumbOffset = mThumbSize * (.5f - progressRatio);
        float thumbX = progressRatio * width + leftPadding + thumbOffset;
        float thumbY = getHeight() / 2f + bounds.height() / 2f;
        canvas.drawText(progressText, thumbX, thumbY, mTextPaint);
    }
}

smaple.xml

Use TextThumbSeekBar in your layout xml as following.

<com.yqritc.sample.TextThumbSeekBar
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:max="10"
  android:progress="5"
  android:thumb="@drawable/shape_seek_bar_text_thumb"
  android:thumbOffset="4dp"/>

shape_seek_bar_text_thumb.xml

Define custom thumb drawable as you need like the following.

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="@color/primary_color"/>
    <size
        android:width="@dimen/thumb_size"
        android:height="@dimen/thumb_size"/>
</shape>

Note

If you use image drawable as the thumb instead of xml shape drawable, set the following attribute if the background of your drawable is transparent.

android:splitTrack="false"

DONE.

@ZakAnun
Copy link

ZakAnun commented Apr 30, 2020

I made it with a TextView in onProgressChanged Callback, Haha.. Like this

audioSeekBarIndicate.text = string(R.string.audio_time_result).format(
                    ParseUtils.progressToMSS(progress),
                    ParseUtils.progressToMSS(seekBar.max))
val indicateWidth = audioSeekBarIndicate.width
val thumb = seekBar.thumb
val bounds = thumb.bounds
val seekBarWidth = seekBar.width
val indicatorX = thumb.intrinsicWidth / 2 + bounds.left + seekBar.x
audioSeekBarIndicate.x = when {
        indicatorX < seekBarWidth -> {
            indicatorX
        }
        indicatorX < 0 -> {
            0f
        }
        else -> {
            seekBarWidth.toFloat()
        }
}
if (audioSeekBarIndicate.x > 0 &&
        audioSeekBarIndicate.visibility == View.GONE) {
    audioSeekBarIndicate.visibility = View.VISIBLE
}

@paullok999
Copy link

paullok999 commented Apr 17, 2024

The text can't center in the thumb,unless calculate the offset by the intrinsic width of thumb,like this

val thumbOffset = thumb.intrinsicWidth * (.5f - progressRatio) //use width of thumb to calculate the offset

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment