Setting a View background based on theme attribute crash the app - android

I'm trying to set a ListView background color based on the current theme attribute, but it crash every time the ListView is shown.It seems I'm doing something wrong but I can't see what...
Here's what I'm doing:
First, create the background color:
<resources>
<color name="userlist_background_light">#fff0f0f0</color>
<color name="userlist_background_dark">#ff040404</color>
</resources>
Second, create attributes for my custom themes:
<resources>
<attr name="userlist_background" format="reference|color" />
</resources>
Third, setting this attribute in my themes:
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="Light" parent="Theme.Sherlock.Light">
<item name="userlist_background">#color/userlist_background_light</item>
</style>
<style name="Dark" parent="Theme.Sherlock">
<item name="userlist_background">#color/userlist_background_dark</item>
</style>
</resources>
And finally, using this attribute in the ListView xml:
<ListView
android:id="#+id/user_bar"
android:layout_width="0dip"
android:layout_height="0dip"
android:background="?attr/userlist_background"
android:cacheColorHint="?userlist_background"
android:visibility="gone" />
Even the Eclipse layout view crash. Of course, it works fine if I use a "#color/" directly in the background attribute. It even work if I use say, "?android:attr/colorBackground".
The message error is:
android.view.InflateException: Binary XML file line #8: Error
inflating class android.view.ListView Caused by:
android.content.res.Resources$NotFoundException: Resource is not a
Drawable (color or path): TypedValue{t=0x2/d=0x7f010068 a=-1}
I'm pretty sure I'm doing something wrong, as it works with android attributes, but I haven't be able to find what during my Google searches.
I hope you'll be able to help me!
Many thanks,
Sébastien.

Ok, I fixed it, and it was due to a mistake!
I have two themes.xml files, one for Honeycomb+, and one for Gingerbread-. I've only added the new attributes to the themes.xml targeting Gingerbread-, and was testing on ICS.
Maybe it'll help others who'll make the same mistake!

Related

Error inflating class <unknown> in XML file

My Android app is crashing because of the following error:
Fatal Exception: android.view.InflateException Binary XML file line
#100 in com.example.myapp:layout/floating_view: Binary XML file line #100 in com.example.myapp:layout/floating_view: Error inflating class <unknown>
The related section of the xml file floating_view.xml, where line #100 is the textColor:
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="?attr/textColor" />
Here it's obviously about the attribute and styles. However, my attribute and styles are defined correctly. As you can see below in my styles.xml, the attribute textColor has a corresponding value in each theme.
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="textColor">#20282D</item>
</style>
<style name="AppThemeLight" parent="AppTheme">
<item name="textColor">#20282D</item>
</style>
<style name="AppThemeDark" parent="AppTheme">
<item name="textColor">#FFFFFF</item>
</style>
</resources>
However as I dig further in the error log, it has traces of some other theme names:
Caused by java.lang.UnsupportedOperationException Failed to resolve
attribute at index 4: TypedValue{t=0x2/d=0x7f040289 a=-1},
theme={InheritanceMap=[id=0x103013fandroid:style/Theme.DeviceDefault.Light.DarkActionBar,
id=0x1030238android:style/Theme.Material.Light.DarkActionBar,
id=0x1030237android:style/Theme.Material.Light,
id=0x103000candroid:style/Theme.Light,
id=0x1030005android:style/Theme],
Themes=[android:style/Theme.DeviceDefault.Light.DarkActionBar,
forced]}
As you can see above, the log from the affected device mentions some themes like Theme.DeviceDefault.Light.DarkActionBar, android:style/Theme.Material.Light etc.. I initially thought it's because my textColor is not defined in those themes. But I have added only 3 themes, and how can I add my custom attribute inside Android's own themes? Do you think the error is because of that, or what else could this error be about?
Also, retrieving the colors in Java code by providing a default value could be an option. However I have so many colors used in my layouts (only in XML) and moving them all to Java is not really ideal in this case.
Any help is appreciated, thanks!

Weird crash "android.view.InflateException: Binary XML file line #9: Error inflating class <unknown>" about declare-styleable

To implement theming, I defined my custom style attributes to avoid overriding system styles
themes.xml
<declare-styleable name="MyThemeBase">
<attr name="myTextColorHighlight" format="reference|color"/>
</declare-styleable>
<style name="MyThemeBase" parent="#style/Theme.AppCompat.Light">
...
</style>
<style name="MY.Theme.AppCompat.Light.Orange" parent="SCThemeBase">
<item name="myTextColorHighlight">#color/textcolor_highlight_orange</item>
</style>
<style name="MY.Theme.AppCompat.Light.Blue" parent="SCThemeBase">
<item name="myTextColorHighlight">#color/textcolor_highlight_blue</item>
</style>
I also defined custom TextAppearance
styles.xml
<style name="My.TextAppearance.Medium" parent="#android:style/TextAppearance.Medium">
<!-- this line caused crash -->
<item name="android:textColor">?attr/myTextColorHighlight</item>
<!-- this worked -->
<!--<item name="android:textColor">#color/textcolor_highlight_orange</item>-->
</style>
In the layout xmls, some TextViews referenced above MY.TextAppearance.Medium style, everything looked so far so good. But I got crash while layouting one TextView which was in a ListView, the stacktrace was
android.view.InflateException: Binary XML file line #9: Error inflating class <unknown>
at android.view.LayoutInflater.createView(LayoutInflater.java:619)
at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
at android.view.LayoutInflater.onCreateView(LayoutInflater.java:666)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:691)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:752)
at android.view.LayoutInflater.inflate(LayoutInflater.java:495)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at com.xxx.yyy.MyListAdatper.getView(MyListAdatper.java:46)
The most weird was other TextViews in same style were good
I've no idea why I ran into this. With some debugging I just found that it worked only if I used direct color instead of attr reference (please check out comment in above styles.xml) in definition of My.TextAppearance.Medium.
Anyone can help? Thanks.
I think the problem is with your approach. What you have defined is a styleable, that is, a custom attribute that you would like to be able to assign different values to.
Instead, what you want is an attribute reference, which is a constant id that can be assigned different values depending on the theme.
For that, instead of:
<declare-styleable name="MyThemeBase">
<attr name="myTextColorHighlight" format="reference|color"/>
</declare-styleable>
Just put:
<attr name="myTextColorHighlight" format="reference|color"/>
That is, you just need to remove the "declare-styleable" wrapper. That should make it work without problems.

Action bar size in custom xml file

I'm not able to find a way to insert the action bar size attribute in my own xml file. Since I'm using Google maps in my activity, I can't use the built-in xml attribute at all in my layout, but I have to call setPadding() on the map using the action bar size. Now, I found the way to retrieve the actionBarSize at runtime, but I wonder if I could skip this code completly, inserting the android attribute in my onw xml, for example:
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<dimen name="myownsize">#android:attr/actionBarSize</dimen>
</resources>
But in this way it doesn't work. Is there a way to do it?
Define a attr in your own project. Create res/values/attrs.xml and add this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="myownsize" format="dimension"></attr>
</resources>
In your res/values/styles.xml, under your parent theme definition, initialize this attribute:
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="myownsize">?android:attr/actionBarSize</item>
</style>
Once this is done, you can use ?attr/myownsize as a dimension:
android:padding="?attr/myownsize"
Sorry if I too, misunderstood the question.

Android color selector doesn't work with custom attributes

I've got in attrs.xml
<resources>
<!-- theme specific colors -->
<attr format="reference|color" name="foreground" />
<attr format="reference|color" name="background" />
</resources>
And then in theme.xml
<style name="MyTheme" parent="android:Theme.Black">
<item name="android:windowNoTitle">true</item>
<item name="foreground">#0000FF</item>
<item name="background">#00FF00</item>
</style>
I also created color selector named forground_to_background.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="?background"/> <!-- pressed -->
<item android:state_focused="true" android:color="?background"/> <!-- focused -->
<item android:color="?foreground"/> <!-- default -->
</selector>
Now I'd like to use it all together in TextView:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/forground_to_background" />
Unfortunately it doesn't work. Instead of having nice green blue colors I've got only one color - red. TextView is always red. When I change TextView to use "?foreground" color will change. Also when I change in colors selector from "?xxxx" to hardcoded value as "#00f" color start to work.
Where is problem? What am I doing wrong?
Edit:
I believe it is duplicate of problem/bug Can a selector resource use a color defined in a style?
Edit2:
Moreover when I try use this TextView in ListView application crashes. It cannot parse XML.
You cannot reference ?attr/ when choosing colors for a selector. What you can do, if you want per-theme colors in your selector, is create multiple selectors which reference #color/ and #drawable/, and then have a "reference" attr which associates one of the selectors with the given style.
<attr name="forground_to_background" format="reference" />
You then have to set the text color like
android:textColor="?attr/forground_to_background"
I believe the text was always red because Android was interpreting the attr's integer value as a color (red), rather than using it as a lookup for what you actually wanted.
The reason why this happens is that I have different Context. While inflating Context is aware of my theme attrs, but to the ListView adapter I passed ApplicationContext that wasn't aware of those attrs. Now I don't know why it doesn't know about them ;)
Are you sure if you applying MyTheme to the activity or the textview?
Another thing you can try is that instead of using the "?" operator in your forground_to_background.xml, trying using "#" instead. see if that fixes your problem

Styling Custom Views

I have a few custom views in my Android project and I've added the relevant details to the attrs.xml file. And now I can implement my objects through XML. This works fine.
How do I style these elements? When I try to use my custom attributes in the styles.xml is get an error "No resource found that matches the given name:"
For using the custom views in normal xml developement I use xmlns:app="http://schemas.android.com/apk/res/bla.bla.bla". What is the correct for use in styles?
This is what my style looks like currently
<style name="Journey_DaySelect_Sunday">
<item name="app:onImage">#drawable/day_sunday_selected</item>
<item name="app:offImage">#drawable/day_sunday</item>
</style>
After more intensive searching on Google I gave up finding it answered elsewhere, and by chance tried using the absolute namespace of my generated R file it worked. May this solve all your problems.
USE THE NAMESPACE CONTAINING YOUR R FILE
<style name="Journey_DaySelect_Sunday" parent="Journey_DaySelect">
<item name="AppZappy.NIRailAndBus:onImage">#drawable/day_sunday_selected</item>
<item name="AppZappy.NIRailAndBus:offImage">#drawable/day_sunday</item>
</style>
For clarification, the item's name attribute should be the same as what is in the attrs.xml's declare-styleable name attribute + ":" + the attribute name.
For example:
attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="com.chuck.norris">
<attr name="actionBarTextColor" format="color"/>
</declare-styleable>
</resources>
style.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="myNewStyle">
<item name="android:textColor">#FFFF0000</item>
<item name="com.chuck.norris:actionBarTextColor">#ffff0000</item>
</style>
</resources>
You can then apply this style to all activities by using a theme in your manifest.xml file. Anywhere that a custom view exists that wants to use the "actionBarTextColor" attribute, you can then use the Java code:
TypedArray typedArray = context.obtainStyledAttributes(attrSet, R.styleable.com_chuck_norris);
COLOR_ACTION_BAR_TEXT = typedArray.getColor(R.styleable.com_chuck_norris_actionBarTextColor, 0xff0000ff);
typedArray.recycle();
I'm not sure why you cannot just define your schema in your style.xml file as was asked above, but it seems to be a limitation of style.xml.
try this solution
<style name="Journey_DaySelect_Sunday">
<item name="onImage">#drawable/day_sunday_selected</item>
<item name="offImage">#drawable/day_sunday</item>
</style>
reference(Chinese)
if you guys think it useful,I will translate it.

Categories

Resources