从主题设置textColor仅在HTC Desire HD上失败

时间:2011-04-07 11:27:52

标签: android coding-style themes textcolor

问题:

我的应用在大多数设备上运行良好,但在 HTC Desire HD (Android 2.2.1)上崩溃。 (编辑:错误仍然存​​在于2.3.3)

异常类 - android.content.res.Resources$NotFoundException

来源方法 - Resources.loadColorStateList()

详情:

我正在使用主题设置textColor。我在布局xml文件中的TextView中声明了textColor ...

<TextView
    android:id="@+id/accountWarning"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/accountWarning"
    android:textSize="20sp"
    android:layout_marginTop="10dp"
    android:padding="10dp"
    android:textColor="?textColor"/>

并声明每个主题的textColor应该在资源主题文件中...

<style name="Theme.TxtoolsDark" parent="Theme">
  <item name="textColor">#FFFFFF</item>
  <item name="autoCompleteTextViewTextColor">#000</item>    
</style>

<style name="Theme.TxtoolsLight" parent="Theme" >
  <item name="textColor">#000</item>
  <item name="autoCompleteTextViewTextColor">#000</item> 
</style>

如果我只是在我的xml文件中对textColor进行硬编码,它可以正常工作,所以似乎无法理解'?textColor'应该让我看看我的themes.xml文件。同样,这在我测试的其他设备上运行良好,但在HTC Desire HD上失败了。

错误:

堆栈跟踪的相关位是......

android.view.InflateException: Binary XML file line #10: Error inflating class <unknown>

Caused by: android.content.res.Resources$NotFoundException: File res/drawable-hdpi/scrollbar_handle_vertical.9.png from drawable resource ID #0x0: .xml extension required
at android.content.res.Resources.loadColorStateList(Resources.java:1842)
at android.content.res.TypedArray.getColorStateList(TypedArray.java:342)
at android.widget.TextView.<init>(TextView.java:665)

编辑: Eclipse 3.5.2向我报告'无法解析颜色值'?textColor“在我的layout.xml的图形布局选项卡中的属性”textColor“中。但是,我仍然可以编译和构建,它仍然适用于除HTC Desire HD之外的所有其他设备。完整的代码在这个问题的底部。

编辑:2011年7月1日

我注意到我有两个单独的堆栈跟踪(尽管我认为它的末端附近只有1行变化)...

java.lang.RuntimeException: Unable to resume activity  {uk.co.txttools.mobile.android.txttoolsmobile/uk.co.txttools.mobile.android.txttoolsmobile.pages.home.HomeTabs}: java.lang.RuntimeException: Unable to resume activity {uk.co.txttools.mobile.android.txttoolsmobile/uk.co.txttools.mobile.android.txttoolsmobile.pages.home.StandardHome}: android.view.InflateException: Binary XML file line #10: Error inflating class <unknown>
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3399)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3420)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2864)
at android.app.ActivityThread.access$2300(ActivityThread.java:136)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2179)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:143)
at android.app.ActivityThread.main(ActivityThread.java:5073)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: Unable to resume activity {uk.co.txttools.mobile.android.txttoolsmobile/uk.co.txttools.mobile.android.txttoolsmobile.pages.home.StandardHome}: android.view.InflateException: Binary XML file line #10: Error inflating class <unknown>
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3399)
at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:170)
at android.app.LocalActivityManager.dispatchResume(LocalActivityManager.java:521)
at android.app.ActivityGroup.onResume(ActivityGroup.java:58)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1260)
at android.app.Activity.performResume(Activity.java:4011)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3389)
... 12 more
Caused by: android.view.InflateException: Binary XML file line #10: Error inflating class <unknown>
at android.view.LayoutInflater.createView(LayoutInflater.java:513)
at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:563)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:618)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:621)
at android.view.LayoutInflater.inflate(LayoutInflater.java:407)
at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:217)
at android.app.Activity.setContentView(Activity.java:1701)
at uk.co.txttools.mobile.android.txttoolsmobile.pages.home.Home.createHomePage(Home.java:88)
at uk.co.txttools.mobile.android.txttoolsmobile.pages.home.StandardHome.createHomePage(StandardHome.java:74)
at uk.co.txttools.mobile.android.txttoolsmobile.pages.home.Home.onResume(Home.java:291)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1260)
at android.app.Activity.performResume(Activity.java:4011)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3389)
... 18 more
Caused by: java.lang.reflect.InvocationTargetException
at android.widget.TextView.<init>(TextView.java:355)
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:446)
at android.view.LayoutInflater.createView(LayoutInflater.java:500)
... 33 more
Caused by: android.content.res.Resources$NotFoundException: File res/drawable-hdpi/scrollbar_handle_vertical.9.png from drawable resource ID #0x0: .xml extension required
at android.content.res.Resources.loadColorStateList(Resources.java:1842)
at android.content.res.TypedArray.getColorStateList(TypedArray.java:342)
at android.widget.TextView.<init>(TextView.java:665)
... 37 more

java.lang.RuntimeException: Unable to resume activity {uk.co.txttools.mobile.android.txttoolsmobile/uk.co.txttools.mobile.android.txttoolsmobile.pages.home.HomeTabs}: java.lang.RuntimeException: Unable to resume activity {uk.co.txttools.mobile.android.txttoolsmobile/uk.co.txttools.mobile.android.txttoolsmobile.pages.home.StandardHome}: android.view.InflateException: Binary XML file line #10: Error inflating class <unknown>
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2485)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2506)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1856)
at android.app.ActivityThread.access$1500(ActivityThread.java:132)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1038)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:143)
at android.app.ActivityThread.main(ActivityThread.java:4293)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: Unable to resume activity {uk.co.txttools.mobile.android.txttoolsmobile/uk.co.txttools.mobile.android.txttoolsmobile.pages.home.StandardHome}: android.view.InflateException: Binary XML file line #10: Error inflating class <unknown>
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2485)
at android.app.LocalActivityManager.moveToState(LocalActivityManager.java:170)
at android.app.LocalActivityManager.dispatchResume(LocalActivityManager.java:521)
at android.app.ActivityGroup.onResume(ActivityGroup.java:58)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1242)
at android.app.Activity.performResume(Activity.java:4004)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2475)
... 12 more
Caused by: android.view.InflateException: Binary XML file line #10: Error inflating class <unknown>
at android.view.LayoutInflater.createView(LayoutInflater.java:518)
at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:568)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:623)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:626)
at android.view.LayoutInflater.inflate(LayoutInflater.java:408)
at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:231)
at android.app.Activity.setContentView(Activity.java:1742)
at uk.co.txttools.mobile.android.txttoolsmobile.pages.home.Home.createHomePage(Home.java:88)
at uk.co.txttools.mobile.android.txttoolsmobile.pages.home.StandardHome.createHomePage(StandardHome.java:74)
at uk.co.txttools.mobile.android.txttoolsmobile.pages.home.Home.onResume(Home.java:291)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1242)
at android.app.Activity.performResume(Activity.java:4004)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2475)
... 18 more
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:415)
at android.view.LayoutInflater.createView(LayoutInflater.java:505)
... 33 more
Caused by: android.content.res.Resources$NotFoundException: Resource is not a         ColorStateList (color or path): TypedValue{t=0x2/d=0x7f010001 a=-1}
at android.content.res.Resources.loadColorStateList(Resources.java:1822)
at android.content.res.TypedArray.getColorStateList(TypedArray.java:342)
at android.widget.TextView.<init>(TextView.java:693)
at android.widget.TextView.<init>(TextView.java:382)
... 36 more

编辑:7月4日 - 完整代码

的themes.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="Theme" parent="android:Theme">
    </style>

    <style name="Theme.TxtoolsDark" parent="Theme">
      <item name="textColor">#FFFFFF</item>
      <item name="autoCompleteTextViewTextColor">#000</item> 
    </style>

    <style name="Theme.TxtoolsLight" parent="Theme" >
      <item name="textColor">#000</item>
      <item name="autoCompleteTextViewTextColor">#000</item>
    </style>

</resources>

attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="autoCompleteTextViewTextColor" format="reference|color" />
    <attr name="textColor" format="reference|color" />
</resources>

myLayoutFile.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView android:id="@+id/ScrollView01" 
                android:layout_width="fill_parent" 
                android:layout_height="fill_parent" 
                xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:scrollbars="vertical" android:scrollbarAlwaysDrawVerticalTrack="true">
    <TextView
        android:id="@+id/accountWarning"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/accountWarning"
        android:textSize="20sp"
        android:layout_marginTop="10dp"
        android:padding="10dp"
        android:textColor="?textColor"/>
    <TextView
        android:id="@+id/haveAccountQuestion"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/haveAccountQuestion"
        android:textSize="20sp"
        android:layout_gravity="center_horizontal"
        android:padding="10dp"
        android:textColor="?textColor"/>
    <Button
        android:id="@+id/yes"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:width="80dp"
        android:text="@string/yesHappy"
        android:textSize="15sp"
        android:layout_gravity="center_horizontal"/>
    <Button
        android:id="@+id/no"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:width="80dp"
        android:text="@string/noSad"
        android:textSize="15sp"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="10dp"/>
    <ListView android:id="@android:id/list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:cacheColorHint="#00000000"/>
</LinearLayout>
</ScrollView>

编辑:2011年7月5日我发现如果我使用'android:textColorPrimary'而不是'textColor',HTC Desire HD上不再出现错误,但文字颜色将始终保持不变系统textColor默认。在所有设备上,它都能按预期完美运行。

编辑:2011年7月6日清晨基本上,HTC Desire HD似乎忽略了用'?'设置的任何值。尽管我上一次编辑中描述了半修复,但是我的应用程序稍后会在使用样式的页面上出现错误。

编辑:2011年7月6日下午晚些时候我通过在Java中粗略设置文本颜色(取决于主题)来解决问题。但是,这对我的ListView中使用“样式”的文本不起作用。但是,我现在已经发现,尽管使用了'?textColor',我程序的所有其余部分仍能正常工作!这意味着只有开启屏幕无法正常工作,这表明HTC Desire HD不能及早创建必要的主题或样式来破译'?textColor'! (或类似的东西!)这可能是至关重要的信息!我可以在代码中交换任何东西以使其工作吗?

5 个答案:

答案 0 :(得分:1)

您在评论中提到您在活动上调用setTheme而不是在清单中的活动上设置主题。请确保在super.onCreate调用之前调用setTheme,并在该Activity的onCreate生命周期方法中调用setContent调用。这样可以防止在主题之前使用任何默认主题。

我怀疑发生的是您在布局XML中使用“?textColor”,但此值仅在您的自定义主题和某些设备的默认主题中定义。其他设备在默认主题中没有定义的值。

错误消息是放在那里的一些值,最终解析为不能用作文本​​颜色的资源。文本颜色通常是一个XML状态列表,它指定用于某些状态的颜色,如聚焦,但如果您希望所有状态使用相同的颜色,则有时会使用直接颜色资源。

就像我在另一篇评论中提到的那样,我见过的大多数主题都没有直接的textColor值。相反,他们有一个textViewStyle指向一个具有textColor的样式。如果你想影响更多的东西,你可能想尝试colorForeground。通常textViewStyle将为textColor指定一个XML状态列表文件,然后将colorForeground用于某些状态的颜色。

答案 1 :(得分:0)

此片段不是必需的..主题应该在没有在任何地方明确指定布局中的样式的情况下生效。

 android:textColor="?textColor"

答案 2 :(得分:0)

我最终选择通过重写我的一些xml和Java文件来解决这个问题。这并不理想,因为它会在代码中产生不一致性,并且会过度复杂化那些主题以简化的东西。然而,为了迎合HTC Desire HD用户,我已经屈服于此。如果有人能找到替代解决方案,请在此处发布。

松散地说,我通过在Java静态方法中设置文本颜色来修复我的代码,例如...

public static void setTextColor(TextView tv) {

    if (CURRENT_THEME==TXTTOOLS_LIGHT){
        tv.setTextColor(Color.BLACK);
    }
    else if (CURRENT_THEME==TXTTOOLS_DARK){
        tv.setTextColor(Color.WHITE);
    }
}

或在styles.xml中创建各种样式(每种文本颜色一种),并在Java代码中调用相关的样式。

SimpleCursorAdapter logins;
if (Theme.getTheme()==Theme.TXTTOOLS_LIGHT){
    logins = new SimpleCursorAdapter(this, R.layout.username_row_light_theme, c, from, to);     
}
else if (Theme.getTheme()==Theme.TXTTOOLS_DARK){
    logins = new SimpleCursorAdapter(this, R.layout.username_row_dark_theme, c, from, to);  
}

答案 3 :(得分:0)

“?”语法是引用当前主题中的样式,你在Manifest中设置你的主题吗?我没有在你提供的代码中看到它,所以我假设如果它已经设置,它就在那里完成。 (这可能是另一个Jim评论的原因 - 你的回答表明它没有被设定。)

此外,您已经定义了两次“textColor”属性 - 一次在themes.xml中,另一次在attrs.xml中。任何设备如何知道您指的是哪一个?因为你使用的是“?”语法,系统应该知道查找样式属性,但我不认为它显式检查资源类型。实际上,有效的语法包括资源类型,它可能有助于“?style / textColor”。另外,尝试调用另一个“attrTextColor”来区分它和主题中的“textColor”属性。 (另外,“textColor”在我看来好像是一个糟糕的属性名称,因为它可能与属性“android:textColor”混淆 - 也许你应该将它命名为“txtoolsTextColor”或其他东西。因为系统应该知道查看你的包对于“textColor”资源,它真的应该没关系...除了你有一个错误,这可能是原因......)

答案 4 :(得分:0)

我最近遇到了类似的问题。仅对于Galaxy S 4G,我在给视图膨胀时遇到以下错误:

Caused by: android.content.res.Resources$NotFoundException: File res/drawable-hdpi/scrollbar_handle_vertical.9.png from drawable resource ID #0x0: .xml extension required

这个错误代码非常无益,看起来更有用的是查看堆栈跟踪的顶部,我找到了:

ComponentInfo{com.staircase3.opensignal/com.staircase3.opensignal.library.Tab_Overview}: android.view.InflateException: Binary XML file line #804: Error inflating class </code>

然后在第804行查看有问题的XML文件,我发现设置android:cacheColorHint是个问题。虽然我有自定义主题,但它不适用于我的ListView,而cacheColorHint只是硬编码。修复很简单,如上所述在java:listview.setCacheColorHint中动态设置。

似乎java中的某些视图变量而不是XML通常会导致更少的问题,平铺位图存在一个错误,也可以通过动态地将tile属性发送到java而不是java来解决(参见XML drawable Bitmap tileMode bug?

对于某些型号的手机和布局,似乎在解码所有XML之前,布局会膨胀。但这是猜想,或者至少是一种解决这些问题的启发式方式。