Search code examples
androiduser-interfaceseekbar

SeekBar Thumb position issue


I'm trying to do a "labeled" thumb for my Seekbar. The objective is to customize a text above the thumb every time the Seekbar position changes.

I'm doing this:

        ...
        seekBar = (SeekBar) findViewById(R.id.bet_seek_bar);
        seekBar.setMax(10);
        setSeekBarLabel("0");
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

            @Override
            public void onStopTrackingTouch(SeekBar seekBar)
            {

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar)
            {

            }

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
            {
                setSeekBarLabel(String.valueOf(progress));
            }
        });
    }

    private void setSeekBarLabel(String text)
    {
        BitmapDrawable thumb = Utils.writeOnBitmap(thumbBmp, text, 0, 0, thumbLablePaint);
        seekBar.setThumb(thumb);
    }

After running it, and touch the bar, I'm getting this:

screenshot

I DON'T CARE right now about any text issue (not writing one, porition, etc).

I DO CARE about thumb position relative to the bar progress.

The thumb position should be where the green bar ends. What am I missing?

Regards.


Solution

  • I've ended up extending from SeekBar, and overriding the onMeasure() and onDraw methods(), that was the only way I've found to so the label/thumb thing work.

    Posting it to help others:

    ...
        @Override
        protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
         {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    
            if (labelBackground != null)
            {
    
                viewWidth = getMeasuredWidth();
                barHeight = getMeasuredHeight();// returns only the bar height (without the label);
                setMeasuredDimension(viewWidth, barHeight + labelBackground.getHeight());
            }
    
        }
    
    
    
        @Override
        protected synchronized void onDraw(Canvas canvas)
        {
            if (labelBackground != null)
            {
                barBounds.left = getPaddingLeft();
                barBounds.top = labelBackground.getHeight() + getPaddingTop();
                barBounds.right = barBounds.left + viewWidth - getPaddingRight() - getPaddingLeft();
                barBounds.bottom = barBounds.top + barHeight - getPaddingBottom() - getPaddingTop();
    
                progressPosX = barBounds.left + ((float) this.getProgress() / (float) this.getMax()) * barBounds.width();
    
                labelPos.x = (int) progressPosX - labelOffset;
                labelPos.y = getPaddingTop();
    
                progressDrawable = getProgressDrawable();
                progressDrawable.setBounds(barBounds.left, barBounds.top, barBounds.right, barBounds.bottom);
                progressDrawable.draw(canvas);
    
                labelTextPaint.getTextBounds(labelText, 0, labelText.length(), labelTextRect);
    
                canvas.drawBitmap(labelBackground, labelPos.x, labelPos.y, labelBackgroundPaint);
                canvas.drawText(labelText, labelPos.x + labelBackground.getWidth() / 2 - labelTextRect.width() / 2, labelPos.y + labelBackground.getHeight() / 2 + labelTextRect.height() / 2, labelTextPaint);
    
                thumbX = (int) progressPosX - getThumbOffset();
                thumbDrawable.setBounds(thumbX, barBounds.top, thumbX + thumbDrawable.getIntrinsicWidth(), barBounds.top + thumbDrawable.getIntrinsicHeight());
                thumbDrawable.draw(canvas);
            } else
            {
                super.onDraw(canvas);
            }
        }
    

    Result:

    result