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
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.
The user can touch the thumb and drag left or right to set the current progress level or use the arrow keys. Placing focusable widgets to the left or right of a SeekBar is discouraged.
Step1: Create a new project. After that, you will have java and XML file. Step2: Open your xml file and add a SeekBar and TextView for message as shown below, max attribute in SeekBar define the maximum it can take. Assign ID to SeekBar And TextView.
You can do this via XML. It will work fine in your application.do this simple integration in your XML where you have mentioned the Progress Bar tag. Edit the maxHeight to your desired height what you want to achieve. It will work perfectly.
The SeekBar class is a subclass of ProgressBar , which contains a getProgress() method. Calling PRICEbar. getProgress() will return the value you are looking for.
you can use android: maxHeight in you XML, to limit background height
<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
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:
//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));
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With