使用 attrs 的自定义视图背景导致崩溃

Custom view background using attrs causes crash

我最近一直在尝试在 Android 中尝试使用样式(并且明显失败),试图在自定义视图背景资源中使用 attrs。所以基本上,我想让用户根据需要设置自定义主题。我有一个托管(支持)ViewPager 的主要片段。 ViewPager 中的每个页面都会使用自定义背景填充自定义视图。视图的背景指向一个样式参考,它基本上是一种颜色,由所选主题调整。

属性

<attr name="designBase400" format="reference" />
<attr name="designBase500" format="reference" />
<attr name="designBase700" format="reference" />

为数不多的自定义样式之一

<style name="Theme.ColorScheme.Turquoise" parent="AppTheme">
    <item name="designBase400">@color/design_base_400_turquoise</item>
    <item name="designBase500">@color/design_base_500_turquoise</item>
    <item name="designBase700">@color/design_base_700_turquoise</item>
</style>

<style name="AppTheme" parent="AppBaseTheme">
    <item name="windowActionBar">false</item>
    <item name="android:spinnerItemStyle">@style/SpinnerItem</item>
    <item name="android:spinnerDropDownItemStyle">@style/SpinnerItem.DropDownItem</item>
</style>

对应颜色

<color name="design_base_500_turquoise">#009688</color>
<color name="design_base_700_turquoise">#00796B</color>
<color name="design_base_400_turquoise">#26A69A</color>

背景资源

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
    <solid android:color="?attr/designBase400" />
</shape>

使用后台资源的视图(仅重要部分)

<RelativeLayout
    android:id="@+id/view_entry_hour_container"
    android:layout_width="@dimen/entry_view_circle_dimen"
    android:layout_height="@dimen/entry_view_circle_dimen"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_alignParentTop="true"
    android:layout_centerVertical="false"
    android:background="@drawable/background_circle" >

    <TextView
        android:id="@+id/view_entry_hour"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="false"
        android:layout_alignParentStart="false"
        android:layout_centerHorizontal="true"
        android:layout_centerInParent="true"
        android:layout_centerVertical="true"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textColor="@android:color/white"
        android:textSize="@dimen/entry_view_hour_size"
        android:textStyle="bold" />

</RelativeLayout>

现在我在 ApplicationManifest.xml 中设置了一个示例主题(比如 @style/Theme.ColorScheme.Turquoise),应用程序立即崩溃,引发 InflationException。 The stack trace can be found here. 我完全不知道哪里出了问题。

format="reference" 更改为 format="color" .

实际上这是 Android 问题,它已在 Lollipop 版本中修复,请参考 Google 问题跟踪器 link、https://code.google.com/p/android/issues/detail?id=26251

因此您应该为每个主题创建单独的可绘制对象。

所以我 有点 使用 earlier question 上的回复解决了我的问题。显然,Android 无法处理可绘制对象中的属性引用(这非常不方便)。相反,应该创建对背景可绘制对象的引用,为每个主题创建一个可绘制对象并将每个对象引用到相应的对象。基本上,我最终得到了以下设置:

背景资源

创建新引用

<attr name="designBase400" format="color" />
<attr name="designBase500" format="color" />
<attr name="designBase700" format="color" />

<!-- reference which points to the corresponding background resource -->
<attr name="circleBackground" format="reference" />

将资源引用添加到自定义主题

<style name="Theme.ColorScheme.Turquoise" parent="AppTheme">
    <item name="designBase400">@color/design_base_400_turquoise</item>
    <item name="designBase500">@color/design_base_500_turquoise</item>
    <item name="designBase700">@color/design_base_700_turquoise</item>

    <item name="circleBackground">@drawable/background_circle_turquoise</item>
</style>

<style name="Theme.ColorScheme.Blue" parent="AppTheme">
    <item name="designBase400">@color/design_base_400_blue</item>
    <item name="designBase500">@color/design_base_500_blue</item>
    <item name="designBase700">@color/design_base_700_blue</item>

    <item name="circleBackground">@drawable/background_circle_blue</item>
</style> <!-- and so on ... -->

我对这个解决方案不是很满意,因为从逻辑上讲,我的第一次尝试应该是完美的。我不能说为什么 Android 不接受可绘制对象中的属性,我可能也不会理解。直到有人愿意启发我并提供更好的解决方案,我想我必须坚持下去。