使用 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 不接受可绘制对象中的属性,我可能也不会理解。直到有人愿意启发我并提供更好的解决方案,我想我必须坚持下去。
我最近一直在尝试在 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 不接受可绘制对象中的属性,我可能也不会理解。直到有人愿意启发我并提供更好的解决方案,我想我必须坚持下去。