Add dynamic text over Android SeekBar thumb

Владимир Ѓоргиевски picture Владимир Ѓоргиевски · May 23, 2012 · Viewed 48.1k times · Source

I'm trying to make this custom SeekBar in Android 2.2 and everything I do seems to be wrong! I'm trying to display the value of the seekbar over the thumb image of the SeekBar. Does anybody have some experiences with this?

Answer

Chintan Shah picture Chintan Shah · Mar 22, 2017

I have followed a different approach which provides more possibilities to customize the thumb. Final output will look like following:

enter image description here

First you have to design the layout which will be set as thumb drawable.

layout_seekbar_thumb.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="@dimen/seekbar_thumb_size"
        android:layout_height="@dimen/seekbar_thumb_size"
        android:background="@drawable/ic_seekbar_thumb_back"
        android:gravity="center"
        android:orientation="vertical">

        <TextView
            android:id="@+id/tvProgress"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="0"
            android:textColor="#000000"
            android:textSize="14sp" />

    </LinearLayout>

</LinearLayout>

Here seekbar_thumb_size can be any small size as per your requirement. I have used 30dp here. For background you can use any drawable/icon of your choice.

Now you need this view to be set as thumb drawable so get it with following code:

View thumbView = LayoutInflater.from(YourActivity.this).inflate(R.layout.layout_seekbar_thumb, null, false);

Here I suggest to initialize this view in onCreate() so no need to inflate it again and again.

Now set this view as thumb drawable when seekBar progress is changed. Add the following method in your code:

public Drawable getThumb(int progress) {
        ((TextView) thumbView.findViewById(R.id.tvProgress)).setText(progress + "");

        thumbView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
        Bitmap bitmap = Bitmap.createBitmap(thumbView.getMeasuredWidth(), thumbView.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        thumbView.layout(0, 0, thumbView.getMeasuredWidth(), thumbView.getMeasuredHeight());
        thumbView.draw(canvas);

        return new BitmapDrawable(getResources(), bitmap);
}

Now call this method from onProgressChanged().

seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

                // You can have your own calculation for progress                    
                seekBar.setThumb(getThumb(progress));
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

Note: Also call getThumb() method when you initialize seekBar to initialize it with default value.

With this approach, you can have any custom view on progress change.