Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android seek bar thumb customization

I am trying to create a seekbar. It has to look like below in picture.

enter image description here

Here is my seekbar in layout:

<SeekBar
    android:id="@+id/progress_bar"
    android:layout_width="match_parent"
    android:layout_height="@dimen/progress_bar_height"
    android:minHeight="@dimen/progress_bar_height"
    android:maxHeight="@dimen/progress_bar_height"
    android:progressDrawable="@drawable/progressbar_seek_bar"
    android:thumbOffset="0dp"
    android:thumb="@drawable/progressbar_thumb"
    android:max="100"/>

Here is progressbar_thumb drawable XML:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:gravity="center_horizontal">
        <bitmap android:src="@drawable/img_grabber_body"/>
    </item>
    <item>
        <bitmap android:src="@drawable/img_grabber_knob_long"/>
    </item>
</layer-list>

There are two different images in thumb one vertical line and round knob. My problem is how to use such thumbs in Android seekbar. If I set the thumb in XML it considers width of thumb as width of round knob. Because of this it leaves some space between thumb and progress as you see in below images. I can customize view to show complete thumb but how to remove this extra space around the thumb?

enter image description here

like image 498
Nitin Mathur Avatar asked Dec 21 '25 11:12

Nitin Mathur


1 Answers

I was facing a similar problem. I found really useful this code.

You just have to change where the text is drawn in the onDraw(Canvas canvas)

Hope this could help.

EDIT 1:

Here is my code that put the label with the progression percentage under the seekbar thumb. You just have to change values of label_x and label_y in the onDraw(Canvas canvas) to change the position where the label is drawn.

public class SeekBarWithHint extends android.support.v7.widget.AppCompatSeekBar {
private final int MIN_PROGRESS_VALUE = 0;
private final int MAX_PROGRESS_VALUE = 100;

private Paint mSeekBarHintPaint;
private int mHintTextColor;
private float mHintTextSize;

public SeekBarWithHint(Context context) {
    super(context);
    init();
}

public SeekBarWithHint(Context context, AttributeSet attrs) {
    super(context, attrs);
    TypedArray a = context.getTheme().obtainStyledAttributes(
            attrs,
            R.styleable.SeekBarWithHint,
            0, 0);

    try {
        mHintTextColor = a.getColor(R.styleable.SeekBarWithHint_hint_text_color, 0);
        mHintTextSize = a.getDimension(R.styleable.SeekBarWithHint_hint_text_size, 0);
    } finally {
        a.recycle();
    }

    init();
}

public SeekBarWithHint(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();
}

private void init() {
    setMax(MAX_PROGRESS_VALUE);
    mSeekBarHintPaint = new TextPaint();
    mSeekBarHintPaint.setColor(mHintTextColor);
    mSeekBarHintPaint.setTextSize(mHintTextSize);
}

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

    int label_x = (int) (getThumb().getBounds().centerX());
    int label_y = getHeight();
    canvas.drawText(String.valueOf(getProgress()) + "%", getProgress() > 95 ? label_x - 55 : label_x, label_y, mSeekBarHintPaint);
}

private void animateProgression(int progress) {
    final ObjectAnimator animation = ObjectAnimator.ofInt(this, "progress", MIN_PROGRESS_VALUE, progress);
    animation.setDuration(3000);
    animation.setInterpolator(new DecelerateInterpolator());
    animation.start();
    this.setProgress(progress);
    this.clearAnimation();
}

public void setSeekbarProgress(int progress) {
    animateProgression(progress);
}
}

EDIT 2:

Better use this DescreteSeekBar that do EXACTLY what you are looking for.

like image 127
ilbose Avatar answered Dec 23 '25 01:12

ilbose



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!