如何在Android中的SeekBar下方显示分隔值?

3
我已经在我的一个活动中添加了一个“seekbar”。它的最大值是5。现在,我想在我的“seekbar”下方显示分隔符值(以1递增,如0、1、2、3、4和5)。我该怎么做?
是否有任何系统方法可以实现这一点,而我却没有能力掌握?欢迎任何输入。
注意:我想以编程方式应用任何更改,而不是从xml中进行。数字应该以等间隔分开。尽管我无法精确地编辑它。

enter image description here


我不是很明白你的意思!你想要显示SeekBar的位置吗?就像TextView显示SeekBar的值一样? - kodartcha
假设我们有一个水平的拖动条,滑块指向拖动条的0位置。我想在拖动条下方显示分隔符值,将其分成5个部分,这样当用户在拖动条上滑动滑块时,就可以知道当前拖动条的值。 - Ali_Waris
如果我的回答对您有所帮助,请@HussainChachuliya将其标记为正确答案。 - waleedsarwar86
2个回答

3

我想您希望展示如下图片所示的视图。

enter image description here

如果是这种情况,您需要创建自己的CustomSeekBar,就像给出的代码一样。

CustomSeekBar.java

public class CustomSeekBar extends SeekBar {

private Paint textPaint;

private Rect textBounds = new Rect();

private String text = "";

public CustomSeekBar(Context context) {
    super(context);
    textPaint = new Paint();
    textPaint.setColor(Color.WHITE);

}

public CustomSeekBar(Context context, AttributeSet attrs) {
    super(context, attrs);
    textPaint = new Paint();
    textPaint.setTypeface(Typeface.SANS_SERIF);
    textPaint.setColor(Color.BLACK);

}

public CustomSeekBar(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);


    textPaint = new Paint();
    textPaint.setColor(Color.BLACK);
}

@Override
protected synchronized void onDraw(Canvas canvas) {
    // First draw the regular progress bar, then custom draw our text
    super.onDraw(canvas);


    int progress = getProgress();
    text = progress + "";

    // Now get size of seek bar.
    float width = getWidth();
    float height = getHeight();

    // Set text size.
    textPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
    textPaint.setTextSize(40);
    // Get size of text.
    textPaint.getTextBounds(text, 0, text.length(), textBounds);

    // Calculate where to start printing text.
    float position = (width / getMax()) * getProgress();

    // Get start and end points of where text will be printed.
    float textXStart = position - textBounds.centerX();
    float textXEnd = position + textBounds.centerX();

    // Check does not start drawing outside seek bar.
    if (textXStart <= 1) textXStart = 20;

    if (textXEnd > width) {
        textXStart -= (textXEnd - width + 30);
    }
    // Calculate y text print position.
    float yPosition = height;

    canvas.drawText(text, textXStart, yPosition, textPaint);
}

public synchronized void setTextColor(int color) {
    super.drawableStateChanged();
    textPaint.setColor(color);
    drawableStateChanged();
}


}

在您的Xml文件中使用自定义文件,如下所示。
 <com.waleedsarwar.customseekbar.CustomSeekBar
    android:id="@+id/seekbar"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:max="5"
    android:paddingBottom="16dp" />

我已经更新了我的问题。你能看一下吗?另外,有没有办法用基本的seekbar来实现这个? - Ali_Waris

0

这是另一种方法。我扩展了一个LinearLayout。我放置了SeekBar和另一个LinearLayout(layout_5),其中包含6个文本视图,分别为0-1-2-3-4-5。更好的选择是创建一个动态图像(从SeekBar获取宽度),该图像根据段数具有这些数字。

我强制SeekBar的指示器停在特定点(在您的情况下为6个点)。除此之外,还可以将SeekBar的最大进度值设置为5。这样做也可以实现功能,但用户体验不佳。

public class SegmentedSeekBar extends LinearLayout {

    private int[] preDefinedValues;
    private int currentProgressIndex;
    private SeekBar seekBar;
    private int segmentCount = 5:

    public SegmentedSeekBar(Context context) {
        this(context, null, 0);
    }

    public SegmentedSeekBar(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.seekBarStyle);
    }

    public SegmentedSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.SegmentedSeekBar,
                0, 0);
        try {
           segmentCount =
           a.getInt(R.styleable.SegmentedSeekBar_segmentCount, -1);
        } finally {
           a.recycle();
        }
           init();
    }

    public void init() {
        //this values will be used when you need to set progress
        preDefinedValues = new int[segmentCount];
        for(int i = 0; i < preDefinedValues.length; i++) {
            preDefinedValues[i] = (100/(segmentCount-1)) * i;
        }
        //Get layout_5
        //which is linearlayout with 6 textviews  
        LayoutInflater inflater = (LayoutInflater) getContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View sliderView = inflater.inflate(
                getSliderId(segmentCount), null);
        //seekbar already inside the linearlayout
        seekBar = (SeekBar)sliderView.findViewById(R.id.seek_bar);
        //linear layout is vertically align 
        //so add your 6 textview linearlayout
        addView(sliderView);
        seekBar.setOnTouchListener(seekBarTouchListener);
    }

    private int getSliderId(int size) {
        return R.layout.layout_5;
    }

    //this method sets progress which is seen in UI not actual progress
    //It uses the conversion that we did in beginning
    public synchronized void setProgress(int progress) {
        if(preDefinedValues != null && progress < preDefinedValues.length && progress >= 0) {
            seekBar.setProgress(preDefinedValues[progress]);
            currentProgressIndex = progress;
        }
    }

    //this listener make sure the right progress is seen in ui
    //take action when user finish with changing progress
    SeekBar.OnSeekBarChangeListener onSeekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            int index = 0;
            for(int i = 0; i < preDefinedValues.length; i++) {
                //try to find closest preDefinedvalues by comparing with latest value
                if(Math.abs(seekBar.getProgress() - preDefinedValues[i]) < Math.abs(seekBar.getProgress() - preDefinedValues[index])) {
                    index = i;
                }
            }
            setProgress(index);
        }
    };
}

有没有更简单的方法?因为我只需要显示分割值,并且它应该是动态的,例如,如果我将seekbar的最大值更改为10,则应显示10个分割,以此类推。 - Ali_Waris
原始代码按照您所说的方式工作,非常复杂。我为您简化了它,以便您可以轻松地获得5个部分。我不想复制整个项目。我认为上面的代码已经解释了这个想法。如果您喜欢,请修改并自行使用。 - user2616232

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接