How to change drawable of specific Star in RatingBar? - android

I want to create ratingBar like penalty bar in Football
i created my custom RatingBar by this style:
<?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/circle_grey"/>
<item
android:id="#android:id/secondaryProgress"
android:drawable="#drawable/circle_green"/>
<item
android:id="#android:id/progress"
android:drawable="#drawable/circle_red"/>
More explain:
when user got a goal so change the star drawable by index 2 in ratingBar and if user unsuccessful change star drawabale by index 2 in ratingBar to red drawable.
red drawable
green drawable
gray drawable
my RatingBar
That's what I want
How to do it?

Since you want to change the color of the rating bar based on the condition, you have to do it programatically by changing your layer-list.
say if the player has made a goal.
private static int GREEN = 0; // progress
private static int RED= 1; // secondary progress
private static int YELLOW= 2; // background
RatingBar ratingBar = (RatingBar) findViewById(R.id.ratingBar);
LayerDrawable stars = (LayerDrawable) ratingBar.getProgressDrawable();
stars.getDrawable(GREEN).setColorFilter(Color.GREEN, PorterDuff.Mode.SRC_ATOP);
stars.getDrawable(RED).setColorFilter(Color.RED, PorterDuff.Mode.SRC_ATOP);
stars.getDrawable(YELLOW).setColorFilter(Color.YELLOW, PorterDuff.Mode.SRC_ATOP);
if player hasn't made goal then,
RatingBar ratingBar = (RatingBar) findViewById(R.id.ratingBar);
LayerDrawable stars = (LayerDrawable) ratingBar.getProgressDrawable();
stars.getDrawable(GREEN).setColorFilter(Color.RED, PorterDuff.Mode.SRC_ATOP);
stars.getDrawable(RED).setColorFilter(Color.GREEN, PorterDuff.Mode.SRC_ATOP);
stars.getDrawable(YELLOW).setColorFilter(Color.YELLOW, PorterDuff.Mode.SRC_ATOP);
Note: Make sure you have made the order i have in the layer-list.

Related

Android change drawable solid color programmatically

I have a drawable that is an oval shape with a with check mark inside.
Is it possible to change the oval color programmatically without changing the check mark color ?
Here's my drawable:
<item>
<shape
android:shape="oval">
<solid android:color="#color/black" />
</shape>
</item>
<item>
<bitmap
android:src="#drawable/check_mark"/>
</item>
What I would like to do is only change the solid black color to something else programmatically
It would be easier to just add a second drawables with other "oval"-color and then replace the drawable programmatically.
You can grammatically create a shape using below reference code.
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius(24);
shape.setShape(GradientDrawable.OVAL);
shape.setColor(R.color.red);
imageView.setBackground(shape);
The drawable is an oval and is the background of an ImageView
Get the Drawable from imageView using getBackground():
Drawable background = imageView.getBackground();
Check against usual suspects:
if (background instanceof ShapeDrawable) {
// cast to 'ShapeDrawable'
ShapeDrawable shapeDrawable = (ShapeDrawable) background;
shapeDrawable.getPaint().setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
} else if (background instanceof GradientDrawable) {
// cast to 'GradientDrawable'
GradientDrawable gradientDrawable = (GradientDrawable) background;
gradientDrawable.setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
} else if (background instanceof ColorDrawable) {
// alpha value may need to be set again after this call
ColorDrawable colorDrawable = (ColorDrawable) background;
colorDrawable.setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
}
Compact version:
Drawable background = imageView.getBackground();
if (background instanceof ShapeDrawable) {
((ShapeDrawable)background).getPaint().setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
} else if (background instanceof GradientDrawable) {
((GradientDrawable)background).setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
} else if (background instanceof ColorDrawable) {
((ColorDrawable)background).setColor(ContextCompat.getColor(mContext,R.color.colorToSet));
}

CustomSeekBar with fading alpha color gradient, black thin border, and tiled background

The goal
I'm trying to replicate this Dialog.
The current state
But I've only gotten to this point (showing only the relevant part):
What is missing
A way to add a thin black border surrounding my custom Seekbar's "progress area", and a tiled background restricted to that "progress area".
My code
As it is, my CustomSeekBar (which extends AppCompatSeekBar) works fine for setting a starting and ending color in the code. Here is the function:
public void setGradientColor(#ColorInt int leftColor, #ColorInt int rightcolor) {
grad = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT,
new int[] {leftColor, rightcolor});
setProgressDrawable(grad);
}
But trying to set the background's image ends up looking like my very last seekbar in the The current state image (the background extends outside of the progress area and fills all of the view's area):
aSeekBar.setBackground(context.getDrawable(R.drawable.checker));
aSeekBar.setGradientColor(Color.parseColor("#00000000"), Color.parseColor("#FF000000"));
My checker.xml file in res/drawable:
<?xml version="1.0" encoding="utf-8"?>
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/checkerstile"
android:tileMode="repeat"
/>
For the "Border" part of your question, you just have to add a Stroke to your GradientDrawable :
public void setGradientColor(#ColorInt int leftColor, #ColorInt int rightcolor) {
grad = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT,
new int[] {leftColor, rightcolor});
grad.setStroke(/* stroke width*/, /* int color*/);
setProgressDrawable(grad);
}
For that, it that easy, sorry i can't help for the background.
I've found a viable solution:
int padding = aSeekBar.getPaddingStart();
InsetDrawable bgImg = new InsetDrawable(context.getDrawable(R.drawable.checker), padding);
aSeekBar.setBackground(bgImg);
Combine this with the solution from Olivier for the border and you get this result:

How to change Shape solid color programmatically? [duplicate]

This question already has answers here:
Set android shape color programmatically
(18 answers)
Closed 3 years ago.
How can I change the <solid android:color= /> programmatically?
I defined a custom shape element:
my_item.xml:
<shape android:shape="oval">
<solid android:color="#FFFF0000"/>
</shape>
And reuse it in another layout:
grid_view.xml:
<LinearLayout>
<ImageView ... android:src="#drawable/my_item"
android:id="#+id/myitemid" />
</LinearLayout>
The following does not work:
public class ShapeItemAdapter extends BaseAdapter {
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
view = inflter.inflate(R.layout.grid_view, null);
ImageView shape = (ImageView) view.findViewById(R.id.myitemid);
shape.setBackgroundColor(0xBCCACA); //does not work
}
}
I turned out none of the answers provided here have been correct. Important is: use getDrawable() on the shape, not getBackground().
GradientDrawable shape = (GradientDrawable) icon.getDrawable();
shape.setColor(Color.BLACK);
Try This:-
Get your drawable from resources and change shape color.Then you can set as a background of image view.
GradientDrawable drawable = (GradientDrawable) mContext.getResources()
.getDrawable(R.drawable.todo_list_circle);
drawable.mutate();
drawable.setColor(mColor);
try this
ImageView shape = (ImageView) view.findViewById(R.id.myitemid);
GradientDrawable bgShape = (GradientDrawable)shape.getBackground();
bgShape.setColor(Color.BLACK);
Get ShapeDrawable and set color:
ImageView shape = (ImageView) view.findViewById(R.id.myitemid);
ShapeDrawable shapeDrawable = (ShapeDrawable) shape.getBackground();
shapeDrawable.getPaint().setColor(ContextCompat.getColor(context,R.color.my_color));
You may wait until layout has been drawn:
ViewTreeObserver to = shape.getViewTreeObserver();
to.addOnGlobalLayoutListener (new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
ImageView shape = (ImageView) view.findViewById(R.id.myitemid);
ShapeDrawable shapeDrawable = (ShapeDrawable) shape.getBackground();
shapeDrawable.getPaint().setColor(ContextCompat.getColor(context,R.color.my_color));
}
});

Palette colour overrides Outline

I'm making an app just to check out some of the new L APIs, and I'm particularly interested in the FloatingActionButton and the Palette colour generator. So I set a full screen ImageView to display an HTC wallpaper, I then extract one of the colours with Palette and set it as the background colour of my FAB. However, doing this removes the Outline from my FAB, so it's no longer circular.
I would like to know how, if possible, to stop the Palette overriding the Outline.
The Palette AsyncListener:
MyActivity.java
Palette.generateAsync(BitmapFactory.decodeResource(getResources(),R.drawable.wallpapers_07),
new Palette.PaletteAsyncListener() {
#Override
public void onGenerated(Palette palette) {
PaletteItem item = palette.getLightVibrantColor();
ImageButton button = (ImageButton) findViewById(R.id.fab);
if (item != null) {
button.setBackgroundColor(item.getRgb());
}
}
});
Outline in MyActivity.java
int size = getResources().getDimensionPixelSize(R.dimen.fab_size);
Outline outline = new Outline();
outline.setOval(0, 0, size, size);
findViewById(R.id.fab).setOutline(outline);
FAB background drawable
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?android:colorControlHighlight">
<item>
<shape android:shape="oval">
<solid android:color="?android:colorAccent"/>
</shape>
</item>
You are replacing the background drawable (RippleDrawable) with a color (ColorDrawable). Instead, you want to change the color of the shape (GradientDrawable) contained with the background drawable.
Try changing the color filter instead:
findViewById(R.id.fab).getBackgroundDrawable().setColorFilter(
new PorterDuffColorFilter(item.getRgb(), Mode.SRC_IN));
If you're changing the color often, you can just cache the color filter object and use setColor(int) followed by findViewById(R.id.fab).invalidate() to update the view.

How to easily change the color of a progressBar in Android?

I would like to dynamically update the ProgressBar Color, in order to match with the layout of the application that changes in realtime.
The idea is to change the color according to the value set.
I found some solution but seems heavy to have that running in an animation updating several times per second.
Use ProgressBar's method:
public void setProgressDrawable (Drawable d)
and pass Drawable in different colors, ex. ColorDrawable which has setColor(int color) method.
To change png drawable colors on the fly try: How to change colors of a Drawable in Android?
EDIT:
ProgressBar drawable is LayerDrawable that looks like:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#android:drawable/screen_progress_frame" />
<item>
<scale scaleWidth="100%" scaleGravity="0x3" drawable="#android:drawable/screen_progress_inner" />
</item>
</layer-list>
It has ScaleDrawable which you want to colorize.
Create your own LayerDrawable similar to the above and extract bar drawable and change color of it.
This is solution which you can use in code (based on the solution of pawelzieba).
ProgressBar progressBar = new ProgressBar(context, null, android.R.attr.progressBarStyleHorizontal);
progressBar.setProgressDrawable(new LayerDrawable(
new Drawable[] {
new ColorDrawable(Color.RED),
new ScaleDrawable(new ColorDrawable(Color.GREEN), Gravity.LEFT, 1, -1),
}));
...
progressBar.setProgress(20);
Well, for anyone looking for how to do it programmatically: do not forget to set ids to your Drawables!
Drawable bckgrndDr = new ColorDrawable(Color.RED);
Drawable secProgressDr = new ColorDrawable(Color.GRAY);
Drawable progressDr = new ScaleDrawable(new ColorDrawable(Color.BLUE), Gravity.LEFT, 1, -1);
LayerDrawable resultDr = new LayerDrawable(new Drawable[] { bckgrndDr, secProgressDr, progressDr });
//setting ids is important
resultDr.setId(0, android.R.id.background);
resultDr.setId(1, android.R.id.secondaryProgress);
resultDr.setId(2, android.R.id.progress);
Setting ids to drawables is crucial, and takes care of preserving bounds and actual state of progress bar.
(It seeems that solution proposed by vmayatskii sort of works - but only if you call setProgress(value) aftrawards, and this value has to be different from current progress value)

Categories

Resources