【问题标题】:Shape Drawable parameters depending on applied style形状可绘制参数取决于应用的样式
【发布时间】:2013-11-22 08:23:36
【问题描述】:

假设我有一个简单的可绘制形状,如下所示:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:dither="true"
    android:innerRadiusRatio="3"
    android:shape="ring"
    android:thicknessRatio="36"
    android:useLevel="false" >

    <gradient
        android:centerColor="@android:color/holo_blue_bright"
        android:centerY="0.001"
        android:endColor="@android:color/holo_blue_dark"
        android:gradientRadius="202.5"
        android:startColor="@android:color/transparent"
        android:type="radial"
        android:useLevel="false" />

</shape>

我将此形状应用为视图背景,如下所示:

<View
    android:layout_width="96dp"
    android:layout_height="96dp"
    android:padding="16dp"
    android:background="@drawable/custom_shape" />

形状的确切细节与这个问题无关——只要说我有一个形状就够了。现在,我不想硬编码形状的各种参数。我们以thicknessRatio 为例。如果我希望根据屏幕配置来改变厚度比,我当然会使用如下整数资源。我会有一个带有以下内容的 values.xml:

&lt;item name="thickness_ratio" type="integer" format="integer"&gt;56&lt;/item&gt;

然后,android:thicknessRatio="@integer/thickness_ratio"

到目前为止,一切都很好。现在,我还希望我的形状有两种“口味”可绘制 - 一种“大”和一种“小”,我希望 查询厚度比,而不是根据配置,而是根据应用的样式到视图。这就是样式和主题的用途。所以,这就是我尝试过的:

第一步:声明一个厚度比的属性(attrs.xml):

<resources>
        <attr name="thicknessRatio" format="reference" />
</resources>

第二步:利用这个属性(styles,xml)声明两种样式:

<style name="CustomShapeSmall">
    <item name="thicknessRatio">@integer/thickness_ratio_small</item>
</style>

<style name="CustomShapeLarge">
    <item name="thicknessRatio">@integer/thickness_ratio_large</item>
</style>

第三步:在values.xml中定义两个整数:

<item name="thickness_ratio_small" type="integer" format="integer">32</item>
<item name="thickness_ratio_large" type="integer" format="integer">56</item>

第四步:查询Shape Drawable中的自定义属性:

android:thicknessRatio="?attr/thicknessRatio"

第 5 步:将所需样式应用于 View

<View
    android:layout_width="96dp"
    android:layout_height="96dp"
    android:padding="16dp"
    style="@style/CustomShapeSmall"
    android:background="@drawable/custom_shape" />

很遗憾,这不起作用。我得到以下异常:

Caused by: android.content.res.Resources$NotFoundException: File res/drawable/custom_shape.xml from drawable resource ID #0x7f020000
    at android.content.res.Resources.loadDrawable(Resources.java:2091)
    at android.content.res.TypedArray.getDrawable(TypedArray.java:601)
    at android.view.View.<init>(View.java:3364)
    at android.view.View.<init>(View.java:3293)
    ... 28 more
Caused by: java.lang.NumberFormatException: Invalid float: "?2130771969"
    at java.lang.StringToReal.invalidReal(StringToReal.java:63)
    at java.lang.StringToReal.parseFloat(StringToReal.java:310)
    at java.lang.Float.parseFloat(Float.java:300)
    at android.content.res.TypedArray.getFloat(TypedArray.java:287)
    at android.graphics.drawable.GradientDrawable.inflate(GradientDrawable.java:827)
    at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:901)
    at android.graphics.drawable.Drawable.createFromXml(Drawable.java:837)
    at android.content.res.Resources.loadDrawable(Resources.java:2087)

从异常堆栈跟踪中,android:thicknessRatio="?attr/thicknessRatio" 行似乎解析为一个问号,后跟 R.attr.thicknessRatio 的整数值 - 但是没有执行进一步解析来实际查询此属性的值。

我在这里错过了什么?


编辑:

Here 是这个问题的完整 github 项目。

【问题讨论】:

    标签: android android-theme android-drawable android-styles


    【解决方案1】:

    显然,无法正确引用 xml drawable 中的属性。

    解决方法是创建不同的可绘制对象(一个比例小,一个比例大),并在不同的样式中使用它们。然后你可以将这些样式应用到你的视图中。

    我已向您发送了一个拉取请求来证明这一点:

    https://github.com/curioustechizen/so-question-android-custom-styles/pull/1

    另见:

    https://stackoverflow.com/a/13471695/1369222

    【讨论】:

    • 看起来这很有效,但没有从样式中获取厚度比率。相反,它似乎采用了默认比率,根据the docs,它是 3。要明白我的意思,请尝试在大形状的情况下硬编码值 56,在小形状的情况下硬编码 32。您会看到戒指“更薄”了很多。
    猜你喜欢
    • 1970-01-01
    • 2020-03-03
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 1970-01-01
    • 1970-01-01
    • 2016-10-11
    • 2017-09-12
    相关资源
    最近更新 更多