-->

Android custom RatingBar image artifacts

2019-01-14 15:58发布

问题:

I implemented a custom RatingBar in an application on my ListView items. Custom style ratingbar_red.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/star_off" />
    <item android:id="@android:id/secondaryProgress" android:drawable="@drawable/star_on" />
    <item android:id="@android:id/progress" android:drawable="@drawable/star_on" />
</layer-list>

Here's part of ListItem layout:

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:paddingLeft="15dp" >

    <RatingBar
        android:id="@+id/li_company_rating"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        android:layout_marginBottom="1dp"
        android:isIndicator="true"
        android:numStars="5"
        android:progressDrawable="@drawable/ratingbar_red"
        android:stepSize="1" />

    <Button
        android:id="@+id/li_company_callbtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="0dp"
        android:layout_marginLeft="40dp"
        android:contentDescription="@string/ContentDescription"
        android:drawableLeft="@drawable/phone_icon"
        android:drawablePadding="5dp"
        android:onClick="callbtn_Click"
        android:text="@string/CallButton"
        android:focusable="false"
        android:focusableInTouchMode="false" >
    </Button>

</LinearLayout>

It works, but when the rating is set, I get some strange image artifacts; 2 vertical lines below the pink stars appear on my view:

Here is star_on.png

star_off.png looks okay, and if rating == 0, the lines don't appear.

I'm android beginner, and can't understand what the problem is.

回答1:

Try giving height to RatingBar in xml layout like this:

android:layout_height="30dp" 

30dp or whatever suits you..

Check out why is this happening ??



回答2:

I had this issue to, looked like the bottom edge of custom star image being stretched. You don't have to set the layout_height of rating bar tag. You can set the min/max height on the rating bar (to same as image height).

Example from my styles xml.

<style name="GoldRatingBar" parent="@android:style/Widget.RatingBar">
  <item name="android:minHeight">@dimen/rating_bar_height</item>
  <item name="android:maxHeight">@dimen/rating_bar_height</item>
</style>

Dimens.xml

<dimen name="rating_bar_height">11dp</dimen>

The value should match that of the drawable used. 11 pixel high image, so the rating_bar_height was set to 11dp.



回答3:

Another simple solution woud be to leave a row of empty pixels in the star image using an image editor like photoshop. Then the repeated or stretched row of pixels in the ratingbar would be empty. This aproach solved my issue.



回答4:

I solved this problem in another way. I take my custom star png's, and in image editor add transparent line to the bottom of the image. The problem with vertical lines disappeared on all screens!



回答5:

Its a Icon design issue. The Problem here is the padding around the icon. If you are creating a custom star icon make sure you leave some padding space between the star and the page boundary on which it lies.

If you are not sure how to do it try Android Asset Studio. You can see something like "Padding around Optical Icon" do not keep it to 0 dip.



回答6:

Every body is suggesting something but no body is trying to explain why this happen. I am gonna try to explain it now. Of course this will happen only when you are trying to customise the rating bar images.

Imagine that we have custom image with size 72x72 pixels and this is our resource for XXXHDPI -(it is 4x).

  1. Same image need to have copy inside XXHDPI, XHDPI, HDPI, MDPI and LDPI as well. I will miss last one resource directory for now.
  2. Inside different directories this image need to be as follow:
    • for XXHDPI size copy image need to be 54x54 (this is 3x)
    • for XHDPI size copy image need to be 36x36 (this is 2x)
    • for HDPI size copy image need to be 27x27 (this is 1.5x)
    • for MDPI size copy image need to be 18x18 (this is 1x)
  3. So now in this scenario if your Rating bar has height bigger then 18 dp for example 30 dp, you will see this bad image artefacts below every star image, BECAUSE obviously RatingBar is trying to fill the rest of it's height with something (your Image is 18 dp but the height of the bar is 30dp), so rest 12dp will be filled with this artefacts.

That's why if you set the rating bar height to be fixed size everything COULD be OK but also COULDN'T be OK. All this depends about your custom image size.

I think there has one solution which will work in all possible scenarios and this is :

  1. Create image asset for all devices screens that your app will support XXXHDPI, XXHDPI or what ever you want.
  2. Make sure that if your (MDPI which is 1x) image has for example height 20 pixels, your RatingBar height will not be bigger then 20 dp and everything will be OK.

NOTE: In this whole conversation we talk about dp (density pixels) not in px because if we provide all those image resources in every single res folder we will have chance to work with dp not with px. I hope the last sentence is clear and make sense.

EDIT: The other possible way is to leave some small padding (empty space) , maybe 1px or 2px at the bottom of your custom image. In that case RatingBar view will NOT display those artefacts pixels, because they will be taken from the padding part of your custom image, which actually is just empty (transparent) pixels. I personally think, that this is not the best way, because the image padding will create some space (padding) between RatingBar and the rest Views inside the layout. In that case you will not have absolutely full control of Views space, because some small part has been hard coded inside the custom image (those 2 px padding).



回答7:

Just 2 pixel padding in image star in photoshop. padding in xml not work, just padding star image in photoshop. it's work very good.



回答8:

I fixed my same problem by reducing "layout_height" since my image's height was less than the height that I had in layout_height.



回答9:

Same issue. In my case Put custom star images in /Drawable folder and set "android:layout_height="30dip"

work fine!!