Add Dynamic Text Over Android Seekbar Thumb

Dynamic Text Over Seekbar Thumb Issues

Try this

Point maxSizePoint = new Point();
getWindowManager().getDefaultDisplay().getSize(maxSizePoint);
int maxX = maxSizePoint.x;
textViewScore.setX(textViewScore.getMeasuredWidth() + (val + seekBar.getThumbOffset() / 2) > maxX ? (maxX - textViewScore.getMeasuredWidth() - 16) : val + seekBar.getThumbOffset() / 2);

UPDATE

I've tried with a single seekbar following is the code and output

public class MainActivity extends AppCompatActivity {
int maxX;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SeekBar seekBarScore = findViewById(R.id.seekBarScore);
final TextView textViewScore = findViewById(R.id.textViewScore);
textViewScore.setText("Split Conversions : " + seekBarScore.getProgress());
Point maxSizePoint = new Point();
getWindowManager().getDefaultDisplay().getSize(maxSizePoint);
maxX = maxSizePoint.x;
seekBarScore.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progressValue, boolean fromUser) {
int val = (progressValue * (seekBar.getWidth() - 2 * seekBar.getThumbOffset())) / seekBar.getMax();
textViewScore.setText("Split Conversions : " + progressValue);
int textViewX = val - (textViewScore.getWidth() / 2);
int finalX = textViewScore.getWidth() + textViewX > maxX ? (maxX - textViewScore.getWidth() - 16) : textViewX + 16/*your margin*/;
textViewScore.setX(finalX < 0 ? 16/*your margin*/ : finalX);
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});

}
}

Sample Image

Dynamic text on vertical seek bar thumb

First you need to use custom vertical seek bar see below link
Custom Vertical Seek bar1 Custom Vertical Seek bar2

Next You need Custom View over thumb. so you need to draws some text on over thumb image. the thumb image is white rectangle image. draw text based on seek bar progress. (i.e : 3 miles, 5 miles etc.) Use below method onProgressChanged().

public BitmapDrawable writeOnDrawable(int drawableId, String text){

Bitmap bm = BitmapFactory.decodeResource(getResources(), drawableId).copy(Bitmap.Config.ARGB_8888, true);

Paint paint = new Paint();
paint.setStyle(Style.FILL);
paint.setColor(Color.BLACK);
paint.setTextSize(20);

Canvas canvas = new Canvas(bm);
canvas.drawText(text, 0, bm.getHeight()/2, paint);

return new BitmapDrawable(bm);
}

or

Use TextThumbSeekBar Lib modify based on your requirement.
TextThumbSeekBar

How add text Seekbar thumb?

I've used this function for a solution;

public BitmapDrawable writeOnDrawable(Bitmap thumb, String text) {

Bitmap bm = thumb.copy(Bitmap.Config.ARGB_8888, true);

Paint paint = new Paint();
paint.setStyle(Style.FILL);
paint.setColor(Color.parseColor("#288ca0"));
paint.setTextSize(bm.getHeight() / 3);
paint.setTypeface(type);
Canvas canvas = new Canvas(bm);
canvas.drawText(text , bm.getWidth() / 4 - bm.getWidth()/10,
bm.getHeight() / 2 + bm.getHeight() / 10, paint);

return new BitmapDrawable(bm);
}

How add TextView in middle of SeekBar thumb?

If I understand your question right, you want to place text inside of the thumb on a seekbar like so:

Sample Image

The Android Seekbar doesn't expose any public or protected methods that allows you to set a text in the thumb. So you can't implement a solution with the Android SeekBar as is.

As a solution, you can write your own CustomSeekBar.

The Android SeekBar extends AbsSeekBar. It's in AbsSeekBar that the thumb's position is set, like so:

 private void setThumbPos(int w, Drawable thumb, float scale, int gap) {
int available = w - mPaddingLeft - mPaddingRight;
int thumbWidth = thumb.getIntrinsicWidth();
int thumbHeight = thumb.getIntrinsicHeight();
available -= thumbWidth;

// The extra space for the thumb to move on the track
available += mThumbOffset * 2;

//Determine horizontal position
int thumbPos = (int) (scale * available);

//Determine vertical position
int topBound, bottomBound;
if (gap == Integer.MIN_VALUE) {
Rect oldBounds = thumb.getBounds();
topBound = oldBounds.top;
bottomBound = oldBounds.bottom;
} else {
topBound = gap;
bottomBound = gap + thumbHeight;
}

//Set the thumbs position
thumb.setBounds(thumbPos, topBound, thumbPos + thumbWidth, bottomBound);
}

and in AbsSeekBar's onDraw() method, the thumb is drawn:

mThumb.draw(canvas);

To implement your own SeekBar, you first create a CustomSeekBar class that extends AbsSeekBar. You then override AbsSeekBar's setThumPos() method in your CustomSeekBar class, and there set the position of your own custom thumb.

Your custom thumb would be a View or ViewGroup,e.g. LinearLayout, with a background drawable and a TextView for the percentage progress text.

You then have to decide how to write the percentage progress to the custom thumb. You could write the percentage progress text on the thumb in a new writeTextOnThumb method() called inside setThumbPos(), or you could expose it as a public method in your CustomSeekBar's API.

How to make vertical seekbar with progress text as thumb

Update to Khemraj's answer

Actually changing the thumb is the simple trick as said by Khemraj. But the problem is when rotating the canvas all its contents will rotate(simple logic). When updating the thumb also will reflect this problem. So the simple thing is to make a rotated CustomTextView.

Method to make thumb

 public Drawable getThumb(int progress) {
int width = getWidth();

((TextView) mThumbView.findViewById(R.id.tvProgress)).setText(String.format(Locale.getDefault(), "%d%%", progress));
mThumbView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
Bitmap bitmap = Bitmap.createBitmap(mThumbView.getMeasuredWidth(), mThumbView.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
mThumbView.layout(0, 0, mThumbView.getMeasuredWidth(), mThumbView.getMeasuredHeight());
mThumbView.draw(canvas);
return new BitmapDrawable(getResources(), bitmap);
}

The layout

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center">

<ImageView
android:layout_marginTop="30dp"
android:id="@+id/imageView6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/seek_thumb_gray"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<com.samsung.lighting.presentation.ui.custom_views.RotatedTextView
android:id="@+id/tvProgress"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:gravity="center"
android:text="20%"
android:textColor="#000000"
android:textSize="12sp"
app:angle="90"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView6" />
</android.support.constraint.ConstraintLayout>

The RotatedTextView

public class RotatedTextView extends AppCompatTextView {
private int mRotationAngle = 90;

@Override
protected void onDraw(Canvas canvas) {
if (mRotationAngle == 90) {
canvas.rotate(mRotationAngle);
canvas.translate(0, -getWidth());
} else if (mRotationAngle == -90) {
canvas.rotate(mRotationAngle);
canvas.translate(-getHeight(), 0);
}
super.onDraw(canvas);
}
}

So first we will rotate the Text to 90 or -90 degrees and set as thumb to VerticalSeekBar and in vertical seekbar rotate the canvas to 90 or -90 degrees. So finally we will get the actual result

Here I posted the working example.

Thanks, Khemraj



Related Topics



Leave a reply



Submit