12

我在以编程方式设置 SeekBar 的可绘制进度时遇到问题。当我在 .xml 文件中设置它时,一切正常。

<SeekBar
 android:id="@+id/sb"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 .....
 android:progressDrawable="@drawable/seek_bar"/>

从 .xml 设置

但是,当我尝试从这样的代码中设置它时,我遇到了问题:

seekBar.setProgressDrawable(getResources().getDrawable(R.drawable.seek_bar));

然后背景可绘制对象占据了整个搜索栏,以后我根本无法修改进度 - 拇指移动但进度可绘制仍然填充整个搜索栏。此外,seekbar 失去了圆角。似乎进度可绘制在搜索栏的顶部。

在代码中设置时

我尝试了android progressBar 上提供的解决方案没有更新进度视图/drawable,但它对我不起作用。

4

4 回答 4

26

我通过使用 .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>

在代码中,您可以像这样使用它:

progressBar.setProgressDrawable(getResources().getDrawable(R.drawable.seek_bar));
于 2012-05-16T09:35:33.180 回答
9

The answer given above is for using xml, but just in case someone wanted to do this programmatically I have it below.

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)

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).

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.

于 2014-08-26T20:55:26.490 回答
6

我之前在更改代码中的搜索和进度条时遇到过问题。一旦我实际上必须加载两次drawable才能正确生效。我认为这与更改图像后的填充有关。

我只是在这里猜测,但尝试在之后设置填充

 getResources().getDrawable(R.drawable.seek_bar) // once
 seekBar.setProgressDrawable(getResources().getDrawable(R.drawable.seek_bar)); //twice
 seekBar.setPadding(int,int,int,int)

并且也不会伤害它使其无效。

 seekBar.postInvalidate()

非常hacky,我不喜欢它,但它以前为我解决了类似的问题

于 2012-05-10T14:52:13.313 回答
1

您可以在 XML 中使用 android: maxHeight 来限制背景高度

<SeekBar
    android:id="@+id/original_volume"
    android:layout_width="120dp"
    android:layout_height="wrap_content"
    android:maxHeight="2dp"/>

它不会夹住拇指

于 2018-07-12T08:06:41.517 回答