Question

So I have created a rating bar with new icons, however, when I implement it, the stars look like they are bleeding, see attached:

Rating bar

Here are the style, rating xml, and how they are implemented in the layout:

style:

<style name="GoldRatingBar" parent="@android:style/Widget.RatingBar">
    <item name="android:indeterminateOnly">false</item>
    <item name="android:progressDrawable">@drawable/gold_ratingbar</item>
    <item name="android:indeterminateDrawable">@drawable/gold_ratingbar</item>
    <item name="android:thumb">@null</item>
    <item name="android:isIndicator">true</item>
</style>

rating 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/rating_star_icon_off" />
    <item android:id="@+android:id/secondaryProgress" android:drawable="@drawable/rating_star_icon_half" />
    <item android:id="@+android:id/progress" android:drawable="@drawable/rating_star_icon" />
</layer-list>

Layout:

<TextView

    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:text="Overall rating"
    android:textSize="16sp"
    android:textStyle="bold" />

<RatingBar
    android:id="@+id/review_overall_rating"
    style="@style/GoldRatingBar"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginRight="6dp"
    android:layout_marginLeft="6dp"
    android:rating="3" />

<TextView
    android:id="@+id/review_rating_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:text=""
    android:textStyle="bold" />

Can anyone see where I have gone wrong?

Was it helpful?

Solution 3

I had facing same problem.

In my case blank_star.png height is 17dp so i put android:layout_height="17dp" on RatingBar and my problem is resolve.Try below code:-

<RatingBar
    android:id="@+id/rating"
    style="@style/rating_bar"
    android:layout_width="wrap_content"
    android:layout_height="17dp"
    android:layout_marginRight="5dp"
    android:isIndicator="true"
    android:numStars="5"
    android:stepSize="1.0" />

style/rating_bar.xml

<style name="rating_bar" parent="@android:style/Widget.RatingBar">
    <item name="android:progressDrawable">@drawable/rating_bar_full</item>
    <item name="android:minHeight">18dip</item>
    <item name="android:maxHeight">18dip</item>
</style>

drawable/rating_bar_full

<?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/ratingbar_full_empty"/>
    <item
        android:id="@+android:id/secondaryProgress"
        android:drawable="@drawable/ratingbar_full_empty"/>
    <item
        android:id="@+android:id/progress"
        android:drawable="@drawable/ratingbar_full_filled"/>

</layer-list>

drawable/ratingbar_full_empty

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:drawable="@drawable/blank_star" android:state_pressed="true" android:state_window_focused="true"/>
    <item android:drawable="@drawable/blank_star" android:state_focused="true" android:state_window_focused="true"/>
    <item android:drawable="@drawable/blank_star" android:state_selected="true" android:state_window_focused="true"/>
    <item android:drawable="@drawable/blank_star"/>

</selector>

drawable/ratingbar_full_filled.xml

<item android:drawable="@drawable/filled_star" android:state_pressed="true" android:state_window_focused="true"/>
<item android:drawable="@drawable/filled_star" android:state_focused="true" android:state_window_focused="true"/>
<item android:drawable="@drawable/filled_star" android:state_selected="true" android:state_window_focused="true"/>
<item android:drawable="@drawable/filled_star"/>

OTHER TIPS

i had a similar case and the accepted answer will not resolve it on all screen sizes in fact the solution is very simple, you just need to add padding to the .png image that you are using "2 transparent pixels on each side "

the bleeding ocures because android is repeating the last row of your star image so just make this row transparent

For all who are still looking for an answer and don't want to crop the image: android:minHeight="0dp" helped me

Update. Why is it working? Well, most of all view components have a default min size to follow accessibility/usability google guidelines. And as was mentioned, seems like RatingBar tries to fill the empty space (diff between your own resource and minHeight) by repeating the last 1-2 pixels (personally I don't understand the reason of such desicion). So by setting the android:minHeight="0dp", RatingBar will wrap content by the height of your resource.

The bleeding occurs because the last row of your star image is being repeated. You could fix this by setting the size of the RatingBar to perfectly match the underlying drawable.

The RatingBar never inspects the size of the underlying drawable. So you have to do this yourself. It can be difficult to do this using xml, since your assets may have different sizes for different screen densities. Plus your UX people may change the assets without updating the xml dimensions.

Solution: create a RatingBar that checks the size of its drawables. See below

public class RatingBar extends android.widget.RatingBar {
    private Drawable starDrawable;

    public RatingBar(Context context) {
        this(context, null);
    }

    public RatingBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        starDrawable = getResources().getDrawable(
            R.drawable.your_drawable, context.getTheme());
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // Make sure to account for padding and margin, if you care.
        // I only cared about left padding.
        setMeasuredDimension(starDrawable.getIntrinsicWidth() * 5 
            + getPaddingLeft(), starDrawable.getIntrinsicHeight());
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top