android 搜索栏沿搜索栏显示进度值

android Seekbar show progress value along the seekbar

我有一个 listviewseekbar,每个 seekbar 代表产品价值的 100%。通过移动 seekbar 可以更改 % 值,我想在用户拖动 seekbar 时沿着搜索栏显示值的变化。我 希望添加另一个文本框来更新值。

我更多地关注在搜索栏指针顶部显示小视图的选项,它出现 onStartTracking 并消失 onStopTracking 事件。

有办法实现吗?

检查此 library。您可以使用 'range seekbar with single thumb to true'.

这是一个简单的方法,

  • 在您的 XML
  • 中添加一个 textView
  • 随着 seekBar
  • 的移动改变它的位置
  • 这将使用 setX()
  • 定位它
  • 如果你愿意,你也可以给它的 Y 位置 setY()
  • 如果你想隐藏,写一些逻辑并在你需要的时候让textView可见性消失。

示例:

seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @Override
                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

                    int val = (progress * (seekBar.getWidth() - 2 * seekBar.getThumbOffset())) / seekBar.getMax();
                    textView.setText("" + progress);
                    textView.setX(seekBar.getX() + val + seekBar.getThumbOffset() / 2);
                    //textView.setY(100); just added a value set this properly using screen with height aspect ratio , if you do not set it by default it will be there below seek bar 

                }

或者您可以将 Paint 与您的自定义 SeekBar class 一起使用,而无需任何 TextView

创建 class

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.SeekBar;


public class MySeekBar extends SeekBar {
    public MySeekBar (Context context) {
        super(context);
    }

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

    public MySeekBar (Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onDraw(Canvas c) {
        super.onDraw(c);
        int thumb_x = (int) (( (double)this.getProgress()/this.getMax() ) * (double)this.getWidth());
        float middle = (float) (this.getHeight());

        Paint paint = new Paint();
        paint.setColor(Color.BLACK);
        paint.setTextSize(20);
        c.drawText(""+this.getProgress(), thumb_x, middle, paint);
    }
}

Set/create 你的 SeekBar 在你的 XML

  <yourPackageName.MySeekBar
            android:id="@+id/my_seek_bar"
            android:layout_width="300dp"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_alignParentTop="true"
            android:layout_marginTop="26dp"
            android:max="10"/>

现在从您的 Activity

seekBar = (MySeekBar) findViewById(R.id.my_seek_bar);
seekBar.setOnSeekBarChangeListener(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) {
    }
});

在您的 xml 文件中添加文本视图,您可以使用这样的线性布局:

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <SeekBar
            android:id="@+id/seekBar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:max="1000" />

        <TextView
            android:id="@+id/textView4"
            android:layout_width="80dp"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

    </LinearLayout>

并在 java 文件中,在搜索栏的 onProgressChanged 方法中更改文本视图文本:

    SeekBar sk = (SeekBar) findViewById(R.id.seekBar);
    sk.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

        @Override
        public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
            TextView t=(TextView)findViewById(R.id.textView4);
            t.setText(String.valueOf(i));
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    });

已接受的答案在大多数情况下可能已经足够好了。但是,如果您想要精确度以使文本恰好位于搜索栏拇指的中间,则必须进行更多计算。这是因为文字的宽度不同。比方说,你想显示从 0 到 150 的数字。188 的宽度将不同于 111。因此,你显示的文本将始终向某一侧倾斜。

解决它的方法是测量文本的宽度,将其从搜索栏缩略图的宽度中移除,除以 2,然后将其添加到已接受答案中给出的结果。现在你不会关心数字范围有多大。这是代码:

 override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
                    val value = progress * (seekBar.width - 2 * seekBar.thumbOffset) / seekBar.max
                    label.text = progress.toString()
                    label.measure(0, 0)
                    val textWidth =  label.measuredWidth
                    val firstRemainder = seekThumbWidth - textWidth
                    val result = firstRemainder / 2
                    label.x = (seekBar.x + value + result)
                }

使文本视图真正与拇指中心位置 X 对齐

@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean b) {
    progressTextView.setText(String.valueOf(progress));

    int width = seekBar.getWidth() - seekBar.getPaddingLeft() - seekBar.getPaddingRight();
    int thumbPos = seekBar.getPaddingLeft() + width * seekBar.getProgress() / seekBar.getMax();

    progressTextView.measure(0, 0);
    int txtW = progressTextView.getMeasuredWidth();
    int delta = txtW / 2;
    progressTextView.setX(seekBar.getX() + thumbPos - delta);
}

试试这个我找到的离散 Seekbar 库 here

最简单的方法是使用 Materila Slider,它可以为您添加值标签,而无需编写要跟踪的 textView。

   <com.google.android.material.slider.Slider
        android:id="@+id/continuous_slider"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:valueFrom="0"
       android:stepSize="1"
        app:labelBehavior="withinBounds"
        android:valueTo="100"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"/>