android 搜索栏沿搜索栏显示进度值
android Seekbar show progress value along the seekbar
我有一个 listview
和 seekbar
,每个 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"/>
我有一个 listview
和 seekbar
,每个 seekbar
代表产品价值的 100%。通过移动 seekbar
可以更改 % 值,我想在用户拖动 seekbar
时沿着搜索栏显示值的变化。我不 希望添加另一个文本框来更新值。
我更多地关注在搜索栏指针顶部显示小视图的选项,它出现 onStartTracking
并消失 onStopTracking
事件。
有办法实现吗?
检查此 library。您可以使用 'range seekbar with single thumb to true'.
这是一个简单的方法,
- 在您的 XML 中添加一个
- 随着
seekBar
的移动改变它的位置
- 这将使用
setX()
定位它
- 如果你愿意,你也可以给它的 Y 位置
setY()
- 如果你想隐藏,写一些逻辑并在你需要的时候让
textView
可见性消失。
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"/>