更改SeekBar中的步长值?

61

我有一个SeekBar,希望在移动它的过程中将值从0更改为200。我有一个TextView,在移动SeekBar时显示这些值。但是我不想使用该区间内的每个值(0、1、2、3、4、5 ...),而是要有10、20、30…等。因此,当我移动SeekBar时,我想显示10、20、30、40…一直到200。请问有人可以给我提供提示或示例如何实现吗?


8个回答

122

尝试以下代码

SeekBar seekBar = (SeekBar)layout.findViewById(R.id.seekbar);
seekBar.setProgress(0);
seekBar.incrementProgressBy(10);
seekBar.setMax(200);
TextView seekBarValue = (TextView)layout.findViewById(R.id.seekbarvalue);
seekBarValue.setText(tvRadius.getText().toString().trim());

seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        progress = progress / 10;
        progress = progress * 10;
        seekBarValue.setText(String.valueOf(progress));
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {

    }
});

setProgress(int)用于设置SeekBar的起始值。

setMax(int)用于设置SeekBar的最大值。

如果您想设置SeekBar的边界,则可以在onProgressChanged方法中检查进度条的值。如果进度小于或大于所定义的边界,则可以将进度设置为您定义的边界。


你必须在类中将文本视图和 SeekBar 声明为字段,否则内部类中会出现错误。 - Tony_craft
6
在onProgressChanged中执行progress = progress/10; 和 progress = progress*10; 的逻辑是什么?如果将一个值除以一个常数再乘以同样的常数,它不会变成初始值吗? - Prajeet Shrestha
1
这是progress = progress / 10; progress = progress * 10;的逻辑:E/onProgressChanged:: progress = 19 E/onProgressChanged:: progress / 10 = 1 E/onProgressChanged:: progress * 10 = 10 E/onProgressChanged:: progress = 10 E/onProgressChanged:: progress / 10 = 1 E/onProgressChanged:: progress * 10 = 10 E/onProgressChanged:: progress = 20 E/onProgressChanged:: progress / 10 = 2 E/onProgressChanged:: progress * 10 = 20 E/onProgressChanged:: progress = 21 E/onProgressChanged:: progress / 10 = 2 E/onProgressChanged:: progress * 10 = 20 E/onProgressChanged:: progress = 20 - Sjd
@Sjd 那么 seekBar.incrementProgressBy(10); 的作用是什么? - OnePunchMan
1
我认为将数字除以10再乘以10的逻辑是因为我们在除以10时会截断最后一位数字。例如,如果当前值为173,则除以10将得到17(因为我们将其存储为整数)。将其乘以10将得到170。基本上,10是您想要增加或减少滑块的步长。 - Dhruv Sangvikar
显示剩余9条评论

26

您可以使用android:stepSize属性,通过材料组件库提供的Slider来实现:

    <com.google.android.material.slider.Slider
        android:valueFrom="0"
        android:valueTo="200"
        android:stepSize="10"
       ..>

输入图片说明


19

我能想到的最简单的方法就是定义:

SeekBar yourSeekBar = (SeekBar)findViewById(R.id.yourSeekBarId);
yourSeekbar.setMax(20);

接下来,覆盖这些方法(即使它们是空的方法,也是必需的):

yourSeekbar.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) {
            if (fromUser) {
                if (progress >= 0 && progress <= sizeSeekBar.getMax()) {                        

                    String progressString = String.valueOf(progress * 10);
                    yourTextView.setText(progressString); // the TextView Reference
                    seekBar.setSecondaryProgress(progress);
                }
            }

        }
    });

该思路是只为SeekBar定义20个值,但总是将该值乘以10并显示该值。 如果你不真正需要200个值,那么使用200个值就没有意义。


3
+1 简单明了。我本来在搜寻其他问题,结果来到这里,但我认为你值得一个加一。 - Tamás Barta
1
这似乎是更好的解决方案。我喜欢它直接跳到下一个数字的方式。在数字静态时进行进展似乎很奇怪。 - Michael Yaworski

3
您也可以通过定义自定义SeekBar类来实现这一点,如下所示。
public class CustomSeekBar extends AppCompatSeekBar {


int SEEKBAR_MULTIPLIER = 1;

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);
}

public void setSeekBarConfig( int SEEKBAR_MULTIPLIER, int SEEKBAR_MAX){
    setMax(SEEKBAR_MAX);
    this.SEEKBAR_MULTIPLIER = SEEKBAR_MULTIPLIER;
}

@Override
public int getProgress() {
    return super.getProgress() * SEEKBAR_MULTIPLIER;
}
}

可以按以下方式使用

 CustomSeekBar mCustomSeekBar = (CustomSeekBar) findViewById(R.id.customSeekBar);
 mSeekBar.setSeekBarConfig(10,20);

在xml中,你应该使用CustomSeekBar而不是SeekBar。

<*.CustomSeekBar
    com.quemb.qmbform.view:setSeekBarConfig="10"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/seekBar" />

为了使您可以在整个应用程序中重复使用自定义SeekBar而无需重复整个额外计算。

3

您应该使用SeekBar.OnSeekBarChangeListener来跟踪进度的变化。调用mseek.setMax(200)。对当前值执行模运算,以决定是否应更新文本视图。

SeekBar.OnSeekBarChangeListener() {

    void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        if (progress % 10 == 0) {
            textview.setText(""+progress);
        }
    }
}

2
如果条形码不够宽或您的手指移动速度很快,这可能会跳过一些值。 - Kris Van Bael
同意。这是我想到的第一件事,但并不是正确的答案。 - Ron
这是一个不错的例子,但@Kris Van Bael是正确的,它跳过了一些值。 - lomza

0

对于最小值问题,您可以在进度条上设置一个偏移量。这样,用户就无法低于您的最小值。

int offset = 10;

seekBar seekBar = (SeekBar)layout.findViewById(R.id.seekbar);
seekBar.setProgress(0);
seekBar.setMax(190); //with the offset, you need to adapt the max value
TextView seekBarValue = (TextView)layout.findViewById(R.id.seekbarvalue);
seekBarValue.setText(""+(seekBar.getProgress() + offset));

seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        progress += offset;

        seekBarValue.setText(String.valueOf(progress));
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {

    }
});

0

一个可能的解决方案是设置 seekBar.setMax(20)(或在 XML 中使用 android:max="20"),并且每当您使用或显示该值时,将其乘以 10。

然后 SeekBar 将至少每次移动 20。


0

使用 Math.round 函数

fun round(n: Int): Int {
    // Smaller multiple
    val a = n / 10 * 10
    // Larger multiple
    val b = a + 10
    // Return of closest of two
    return if (n - a > b - n) b else a
}

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