Android custom RatingBar image artifacts

2019-01-14 16:10发布

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:

enter image description here

Here is star_on.png

link

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.

9条回答
手持菜刀,她持情操
2楼-- · 2019-01-14 16:52

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.

查看更多
The star\"
3楼-- · 2019-01-14 16:53

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

查看更多
爷的心禁止访问
4楼-- · 2019-01-14 16:56

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.

查看更多
登录 后发表回答