如何以编程方式设置 Android SeekBar 进度可绘制
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10536202/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to set Android SeekBar progress drawable programmatically
提问by Milos Pesic
I have a problem with programmatically setting the progress drawable of a SeekBar. When I set it in the .xml file everything is working fine.
我在以编程方式设置 SeekBar 的可绘制进度时遇到问题。当我在 .xml 文件中设置它时,一切正常。
<SeekBar
android:id="@+id/sb"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
.....
android:progressDrawable="@drawable/seek_bar"/>
But, I have a problem when I try to set it from code like this:
但是,当我尝试从这样的代码中设置它时,我遇到了问题:
seekBar.setProgressDrawable(getResources().getDrawable(R.drawable.seek_bar));
Background drawable then takes the whole seek bar, and I'm not able to modify the progress at all later on - the thumb moves but the progress drawable still fills whole seekbar. Also, seekbar looses its rounded corners. It seems that progress drawable is on top of the seekbar.
背景可绘制然后占据整个搜索栏,我以后根本无法修改进度 - 拇指移动但进度可绘制仍然填满整个搜索栏。此外,搜索栏失去了圆角。似乎进度可绘制位于搜索栏的顶部。
I tried the solution provided on android progressBar does not update progress view/drawable, but it doesn't work for me.
我尝试了android progressBar 上提供的解决方案不更新进度视图/可绘制,但它对我不起作用。
回答by Milos Pesic
I solved the problem by using .xml shape as background for my SeekBar. The complete SeekBar solution that can be used via setProgressDrawable() method should be like this:
我通过使用 .xml 形状作为我的 SeekBar 的背景解决了这个问题。可以通过 setProgressDrawable() 方法使用的完整 SeekBar 解决方案应该是这样的:
//seek_bar.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@android:id/background"
android:drawable="@drawable/seek_bar_background"/>
<item android:id="@android:id/progress"
android:drawable="@drawable/seek_bar_progress" />
</layer-list>
//seek_bar_background.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<gradient
android:angle="270"
android:startColor="#8a8c8f"
android:endColor="#58595b" />
<corners android:radius="5dip" />
</shape>
//seek_bar_progress.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@android:id/background"
android:drawable="@drawable/seek_bar_background"/>
<item android:id="@android:id/progress">
<clip android:drawable="@drawable/seek_bar_progress_fill" />
</item>
</layer-list>
//seek_bar_progress_fill.xml
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<gradient
android:startColor="#b3d27e"
android:endColor="#93c044"
android:angle="270"
/>
<corners android:radius="5dip" />
</shape>
In the code, you can use it like this:
在代码中,你可以这样使用它:
progressBar.setProgressDrawable(getResources().getDrawable(R.drawable.seek_bar));
回答by Danuofr
The answer given above is for using xml, but just in case someone wanted to do this programmatically I have it below.
上面给出的答案是使用 xml,但以防万一有人想以编程方式执行此操作,我在下面提供了它。
public class SeekBarBackgroundDrawable extends Drawable {
private Paint mPaint = new Paint();
private float dy;
public SeekBarBackgroundDrawable(Context ctx) {
mPaint.setColor(Color.WHITE);
dy = ctx.getResources().getDimension(R.dimen.one_dp);
}
@Override
public void draw(Canvas canvas) {
canvas.drawRect(getBounds().left,getBounds().centerY()-dy/2,getBounds().right,getBounds().centerY()+dy/2,mPaint);
}
@Override
public void setAlpha(int i) {
mPaint.setAlpha(i);
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
}
}
Above class is for the background of the seekbar (the part that always exists under the progress drawable)
上面的class是seekbar的背景(一直存在于progress drawable下的部分)
public class SeekBarProgressDrawable extends ClipDrawable {
private Paint mPaint = new Paint();
private float dy;
private Rect mRect;
public SeekBarProgressDrawable(Drawable drawable, int gravity, int orientation, Context ctx) {
super(drawable, gravity, orientation);
mPaint.setColor(Color.WHITE);
dy = ctx.getResources().getDimension(R.dimen.two_dp);
}
@Override
public void draw(Canvas canvas) {
if (mRect==null) {
mRect = new Rect(getBounds().left, (int)(getBounds().centerY() - dy / 2), getBounds().right, (int)(getBounds().centerY() + dy / 2));
setBounds(mRect);
}
super.draw(canvas);
}
@Override
public void setAlpha(int i) {
mPaint.setAlpha(i);
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
}
}
Above is the progress drawable. Notice it's a clip drawable. The cool part here is I am setting the bounds to be whatever I want, along with color. This allows for fine tuned customization of your drawable.
以上是可绘制的进度。注意它是一个可绘制的剪辑。这里很酷的部分是我将边界设置为我想要的任何东西,以及颜色。这允许对您的可绘制对象进行微调自定义。
//Custom background drawable allows you to draw how you want it to look if needed
SeekBarBackgroundDrawable backgroundDrawable = new SeekBarBackgroundDrawable(mContext);
ColorDrawable progressDrawable = new ColorDrawable(Color.BLUE);
//Custom seek bar progress drawable. Also allows you to modify appearance.
SeekBarProgressDrawable clipProgressDrawable = new SeekBarProgressDrawable(progressDrawable,Gravity.LEFT,ClipDrawable.HORIZONTAL,mContext);
Drawable[] drawables = new Drawable[]{backgroundDrawable,clipProgressDrawable};
//Create layer drawables with android pre-defined ids
LayerDrawable layerDrawable = new LayerDrawable(drawables);
layerDrawable.setId(0,android.R.id.background);
layerDrawable.setId(1,android.R.id.progress);
//Set to seek bar
seekBar.setProgressDrawable(layerDrawable);
Above code uses custom drawables to edit seek bar. My main reason for doing this is I will be editing the look of the background drawable, so it has "notches" (although not implemented yet). You can't do that with a xml defined drawable (at-least not easily).
上面的代码使用自定义可绘制对象来编辑搜索栏。我这样做的主要原因是我将编辑背景可绘制的外观,因此它具有“缺口”(尽管尚未实现)。您不能使用 xml 定义的可绘制对象(至少不容易)做到这一点。
Another thing I noticed is that this process prevents the SeekBar's from getting as wide as the thumb drawable. It sets the bounds of the drawables so they never get to tall.
我注意到的另一件事是,这个过程会阻止 SeekBar 变得与拇指可绘制一样宽。它设置了可绘制对象的边界,因此它们永远不会变高。
回答by Jason
I've had issues changing seek and progress bars from code before. Once I actually had to load the drawable twice before it took effect properly. I think it was related to padding after changing the image.
我以前在更改代码中的搜索和进度条时遇到过问题。有一次我实际上不得不在它正确生效之前两次加载可绘制对象。我认为这与更改图像后的填充有关。
I'm just guessing here, but try setting the padding afterwards with
我只是在这里猜测,但之后尝试设置填充
getResources().getDrawable(R.drawable.seek_bar) // once
seekBar.setProgressDrawable(getResources().getDrawable(R.drawable.seek_bar)); //twice
seekBar.setPadding(int,int,int,int)
and also couldn't hurt to invalidate it.
并且也不能伤害它无效。
seekBar.postInvalidate()
Very hacky and I dont like it, but it solved something similar for me before
非常hacky,我不喜欢它,但它之前为我解决了类似的问题
回答by xiao xinpeng
you can use android: maxHeight in you XML, to limit background height
您可以在 XML 中使用 android: maxHeight 来限制背景高度
<SeekBar
android:id="@+id/original_volume"
android:layout_width="120dp"
android:layout_height="wrap_content"
android:maxHeight="2dp"/>
and it will not clip the thumb
它不会夹住拇指