安卓 - 自定义评分条看起来像是在出血

23

我使用新图标创建了一个评分条,然而当我实现它时,星星看起来像在流血,见附图:

评分条

以下是样式、评分xml以及在布局中的实现方式:

样式:

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

评级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>

布局:

<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" />

有人能发现我的错误出在哪里吗?

4个回答

24

我曾遇到过类似的情况,而且已接受的答案并不能解决所有屏幕大小的问题。实际上,解决方案非常简单,只需要在使用的 .png 图像中添加填充 "每边 2 个透明像素"。

出现这种情况是因为 Android 在重复您的星形图像的最后一行,所以只需将此行设置为透明即可。


3
应该接受这个答案!!! 一直在尝试调整,但是在图像上添加2像素的透明填充解决了问题!!! - Marka A

8

对于那些仍在寻找答案且不想裁剪图像的用户: android:minHeight="0dp" 对我有帮助。

更新。 为什么它有效?大多数视图组件都有默认的最小尺寸以遵循辅助性/可用性 Google 指南。而且正如之前提到的,似乎RatingBar试图通过重复最后1-2个像素来填充空白空间(即你自己资源和minHeight之间的差异),但我个人不理解这样做的原因。因此,通过设置 android:minHeight="0dp"RatingBar将会根据你的资源高度自动包裹内容。


7

我曾经遇到过同样的问题。

在我的情况下,blank_star.png 的高度是17dp,因此我在 RatingBar 上加上了 android:layout_height="17dp",问题得以解决。请尝试以下代码:

<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"/>


我确实尝试过,但是在手机上,星星的底部被切掉了,在7英寸的平板电脑上,星星下面有大约1个像素的额外线条。你认为这些图片可能是错误的吗? - James King
减小图像高度,不能说图像有问题或者什么的吗? - duggu
我已经减小了图片的高度,但我只能让其在手机或平板电脑上正常工作,并不能两者兼顾。它总是在一个上面看起来不正确。 - James King
我建议使用不同的布局来支持UI在两个上。 - duggu

1
出现这种情况是因为您的星级图像的最后一行被重复了。您可以通过将RatingBar的大小设置为完全匹配底层可绘制对象来解决此问题。
RatingBar从不检查底层可绘制对象的大小,因此您必须自己进行此操作。使用xml可能很难做到这一点,因为您的资源在不同的屏幕密度下可能具有不同的大小。另外,您的用户体验人员可能会更改资源而不更新xml尺寸。
解决方案:创建一个检查其可绘制对象大小的RatingBar。请参见以下内容。
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());
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接