I'm trying the (surely simple?) task of having a TextView follow the thumb on a progress bar and show the progress in the TextView.
The problem is that for progress values of less than half max, the TextView drifts to the left of the thumb, getting more and more left of the correct place and vice versa with progress values more than half max the TextView drifts more and more to the right.
Below is a version of code that reproduces the problem...
Layout.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".Seekbar_test" >
<SeekBar
android:id="@+id/seekBar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="59"
android:layout_marginTop="24dp" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge" />
And .java
package com.example.seekbar_test;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
public class Seekbar_test extends Activity {
SeekBar fade_seek;
TextView fade_text;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_seekbar_test);
fade_seek = (SeekBar) findViewById(R.id.seekBar1);
fade_text = (TextView) findViewById(R.id.textView1);
fade_seek.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {
say_minutes_left(progress);
}
});
}
private void say_minutes_left(int how_many)
{
String what_to_say = String.valueOf(how_many);
fade_text.setText(what_to_say);
int seek_label_pos = (int)((float)(fade_seek.getMeasuredWidth()) * ((float)how_many / 60f));
fade_text.setX(seek_label_pos);
}
}
This works for me:
private void say_minutes_left(int how_many)
{
String what_to_say = String.valueOf(how_many);
fade_text.setText(what_to_say);
int seek_label_pos = (((fade_seek.getRight() - fade_seek.getLeft()) * fade_seek.getProgress()) / fade_seek.getMax()) + fade_seek.getLeft();
if (how_many <=9)
{
fade_text.setX(seek_label_pos - 6);
}
else
{
fade_text.setX(seek_label_pos - 11);
}
}
Thanks to Pushpendra Kuntal & flightplanner @ unable to get right position of texBox in Thumb of seekbar
Works good with Ken Nichols code, but here is a better decision, for example, to center you TextView to current position in ProgressBar(SeekBar):
private void say_minutes_left(int how_many)
{
String what_to_say = String.valueOf(how_many);
fade_text.setText(what_to_say);
int seek_label_pos = (((fade_seek.getRight() - fade_seek.getLeft()) * fade_seek.getProgress()) / fade_seek.getMax()) + fade_seek.getLeft();
fade_text.setX(seek_label_pos - fade_text.getWidth() / 2);
}
If you have padding in your ProgressBar(SeekBar), you can use more general version of this code:
private void say_minutes_left(int how_many)
{
String what_to_say = String.valueOf(how_many);
fade_text.setText(what_to_say);
int left = fade_seek.getLeft() + fade_seek.getPaddingLeft();
int right = fade_seek.getRight() - fade_seek.getPaddingRight();
int seek_label_pos = (((right - left * fade_seek.getProgress()) / fade_seek.getMax()) + left;
fade_text.setX(seek_label_pos - fade_text.getWidth() / 2);
}
//Get the thumb bound and get its left value
int x = seekBar.getThumb().getBounds().left;
//set the left value to textview x value
textView.setX(x);
use this to move text view according to progress
The following solution works for API >= 15:
Override SeekBar to create the getThumb() method that is not available on api 15:
public class CustomSeekBar extends SeekBar { private Drawable thumb; public CustomSeekBar(Context context) { super(context); } public CustomSeekBar(Context context, AttributeSet attrs) { super(context, attrs); } public CustomSeekBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public void setThumb(Drawable thumb) { super.setThumb(thumb); this.thumb = thumb; } @Override public Drawable getThumb() { return thumb; } }
And use it Like this:
correctX = customSeekBar.getThumb().getBounds().left;
Use this , we are calculating the x position based on progress and setting it to textview
seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
var xPosition= (((seekBar1.right - seekBar1.left) / seekBar1.max) * seekBar1.progress ) + seekBar1.left
textView1.translationX = xPosition.toFloat() - (textView1.width/2)
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {
}
override fun onStopTrackingTouch(seekBar: SeekBar?) {
}
})
TextView must be
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceLarge"
/>
and remove it:
int seek_label_pos = (int)((float)(fade_seek.getMeasuredWidth()) * ((float)how_many / 60f));
fade_text.setX(seek_label_pos);
Hope it's help.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.