Search code examples
androidandroid-seekbar

TextView above SeekBar Thumb is shifted


I'm making a custom SeekBar that has a TextView above the thumb as follows:

enter image description here

The code im using is (the -30 is the width of the textview to center it):

SeekBar.OnSeekBarChangeListener seekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

        int val = (progress * (seekBar.getWidth() - 2 * seekBar.getThumbOffset())) / seekBar.getMax();
        Tv_SbDistanceText.setText(progress + " Km");
        Tv_SbDistanceText.setX(seekBar.getX() + val + seekBar.getThumbOffset() / 2 - 30);

        Show_Map(dpWidth, dpHeight, Lat, Lon, progress*1000);

    }

Thing is, that when I move the thumb the textview is being shifted more and more:

enter image description here

(It is not because of the -30, I tested with and without it)

Is there a way I can make sure it will always stay right above the center of the thumb?

The xml is:

<SeekBar
    android:id="@+id/sb_radius"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:progress="10"
    android:min="1"
    android:max="300"
    android:layout_marginTop="48dp"
    android:layout_marginStart="40dp"
    android:layout_marginEnd="40dp"
    android:thumb="@drawable/sb_thumb"
    android:progressDrawable="@drawable/sb_style"
    app:layout_constraintTop_toBottomOf="@+id/sb_text"
    android:splitTrack="false">
</SeekBar>

Thank you


Solution

  • Its in Kotlin you can convert it easily. Accept the answer, if it helped you.

    sbTest.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener
        {
            override fun onProgressChanged(seekBar: SeekBar?, p1: Int, p2: Boolean) {
    
            val value = seekBar?.progress
            tvPos.text = "$value Km"
            if(value!=0) {
    
                val cur = seekBar!!.width/seekBar.max
    
                tvPos.x = (cur * value!!).toFloat() +10
            }
            tvPos.y = seekBar?.pivotY!! + 10
            Log.d("Pos", tvPos.x.toString() + ": " +seekBar!!.width+":" +seekBar.x)
        }
    

    enter image description here Here's java, Get the max length of seekbar and divide the width of seekbar with it and multiply progress to get exact value of x-axis, adding different values to x-axis so text can stay in middle of point. Subtracting -50 from y-axis, so it can stay on top of point.

    You can adjust if/else according to your need.

                  float value = seekBar.getProgress();
    
                float currentPosition =  (float)seekBar.getWidth() / seekBar.getMax();
    
                currentPosition = currentPosition * value;
    
                Tv_SbDistanceText.setText(value + " Km");
    
                if(value<100)
                    Tv_SbDistanceText.setX(currentPosition +50);
                else
                    Tv_SbDistanceText.setX(currentPosition+10);
    
                Tv_SbDistanceText.setY(seekBar.getY() - 50);
    

    enter image description here