Referencing a selector causes an InflationException - android

I'm trying to develop two themes for my app, and depending on the theme, I need a View to use a different selector. Though when I create a reference which determines the correct selector to use, I get an InflationException error.
Here's my attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ReditrTheme">
<attr name="downvoteArrow" format="reference" />
<attr name="upvoteArrow" format="reference" />
</declare-styleable>
<declare-styleable name="VoteState">
<attr name="enabled" format="boolean" />
</declare-styleable>
</resources>
Here's my themes.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="DarkTheme" parent="#android:style/Theme.Holo">
<item name="upvoteArrow">#drawable/upvote_states</item>
<item name="downvoteArrow">#drawable/downvote_states</item>
</style>
<style name="LightTheme" parent="#android:style/Theme.Holo.Light">
<item name="upvoteArrow">#drawable/upvote_states_l</item>
<item name="downvoteArrow">#drawable/downvote_states_l</item>
</style>
</resources>
Here's my upvote_states.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res/com.reditr.app">
<item android:drawable="#drawable/ic_action_arrow_top_colored" app:enabled="true"/>
<item style="#drawable/ic_action_arrow_top" app:enabled="false"/>
</selector>
Here's my upvotes_states_l.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res/com.reditr.app">
<item android:drawable="#drawable/ic_action_arrow_top_colored" app:enabled="true"/>
<item style="#drawable/ic_action_arrow_top_l" app:enabled="false"/>
</selector>
downvotes_states.xml and downvotes_states_l.xml are identical to the ones above, they just use ic_action_arrow_bottom instead.
Finally, here's my View that I'm trying to apply the reference to:
<com.example.views.UpvoteView
android:id="#+id/upvote"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:scaleType="fitCenter"
android:src="?attr/upvoteArrow" />
I tried a few solutions online but they were always a bit slightly different to my issue and didn't fix my problem.
Thanks in advance!

Just realized the mistake I made. In my states.xml files, I used the style attribute for some reason, it should have been android:drawable.

Related

Android: Using attributes in selector

I'm trying to create a selector that uses attributes defines by the selected theme.
attrs.xml
<declare-styleable name="ThemeColors">
<attr name="buttonTextColor" format="color" />
</declare-styleable>
selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:color="#android:color/black" />
<item android:color="?attr/buttonTextColor"/>
</selector>
Theme:
<style name="Theme.Test" parent="#style/Theme.AppCompat">
<item name="buttonTextColor">#android:color/white</item>
</style>
Part of the layout file:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/test"
android:textColor="#drawable/selector" />
Manifest
<application
...
android:theme="#style/Theme.Test" >
The layout file is inflated by the setContentView method.
Now the problem is that the textcolor is RED in the unpressed state (and black when pressed). It seems like it cannot find the buttonTextColor and uses the default RED(?)
Already tried to set the theme to the Application Context, but no luck..
Thanks in advance.

Inflate layout with defined style

I'm implementing and app with a custom list adapter. When I inflate each list item which have a defined style the style doesn't seem to work.
I call the inflate doing this:
convertView = inflater.inflate(R.layout.widget,null);
The layout is this one:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="?widgetWrapperStyle">
<LinearLayout
style="#style/stat" />
<RelativeLayout
style="?widgetStyle"
android:layout_below="#+id/widgetStat" >
<TextView
android:id="#+id/head"/>
<LinearLayout
android:id="#+id/body" />
</RelativeLayout>
My attrs.xml and style.xml are:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="widgetWrapper">
<attr name="widgetWrapperStyle" format="reference" />
</declare-styleable>
<declare-styleable name="widget">
<attr name="widgetStyle" format="reference" />
</declare-styleable>
</resources>
<style name="AppThemeDark" parent="AppBaseThemeDark">
<item name="widgetWrapperStyle">#style/widgetWrapperDark</item>
<item name="widgetStyle">#style/widget</item>
</style>
<style name="widgetWrapperDark" parent="widgetWrapper">
<item name="android:background">#color/list_item_background_dark</item>
</style>
<style name="widget">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:padding">#dimen/widget_padding</item>
</style>
Non of the 'style="?xxxx"' seems to be working. When the view gets inflate the background color is not the correct one.
When inflating layouts, it is important to use a properly-configured LayoutInflater. In particular, it needs to be created from an Activity, ideally by just calling getLayoutInflater() (or getSupportLayoutInflater() for a SherlockActivity and kin, IIRC).
Dave Smith has an excellent blog post reviewing the various types of Context, including covering the issues regarding themes and layout inflation.

How to reference a style in a custom theme

I have a login screen that is branded differently for different builds of my application. I need the background image to be different in the layout file for this screen, so I want to point to a different style for the top level container. I'm a bit at a loss at how to do this.
I have declared a styleable something like:
<resources>
<declare-styleable name="ThemeBase">
<attr name="loginPageContainerStyle" format="reference" />
</declare-styleable>
</resources>
I have several different themes for the application, as such:
<resources>
<style name="ThemeBase" parent="android:style/Theme.Light" />
<style name="ThemeOne" parent="ThemeBase">
<item name="loginPageContainerStyle">#style/loginPageContainerThemeOne</item>
</style>
<style name="ThemeTwo" parent="ThemeBase">
<item name="loginPageContainerStyle">#style/loginPageContainerThemeTwo</item>
</style>
</resources>
And I have defined the following styles:
<resources>
<style name="loginPageContainerThemeOne">
<item name="android:background">#drawable/background_theme_one</item>
</style>
<style name="loginPageContainerThemeTwo">
<item name="android:background">#drawable/background_theme_two</item>
</style>
</resources>
And finally a login.xml file something like:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/loginRoot"
style= [ ? WHAT GOES HERE ? ]
android:gravity="center_horizontal"
android:orientation="horizontal">
[ LAYOUT STUFF ... ]
</LinearLayout>
Am I doing anything wrong? Can this be done this way?
Ok I figured it out, the style reference should be:
style="?attr/loginPageContainerStyle"
Figured I would share.

How to refer android attribute layout_width from custom attribute?

I want to separate the usage of my application on xlarge devices and usage on other devices to restrict layout_width parameter by 720dp for xlarge. For this purpose I create values/attrs.xml:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<attr name="layoutWidth" format="reference|dimension" />
</resources>
with custom parameter layoutWidth to set it in
android:layout_width="?layoutWidth"
Furtner, I need to specify two themes.xml files for xlarge and ordinary devices in values-xlarge and values directories:
values-xlarge/themes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme" parent="android:Theme">
<item name="layoutWidth">720dp</item>
</style>
</resources>
values/themes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme" parent="android:Theme">
<item name="layoutWidth">What should I write here!?</item>
</style>
</resources>
So, how can I make a reference on Android "fill_parent" parameter at this place? It seems like #android:layout_width/fill_parent, but I have compiling Error:
No resource found that matches the given name (at 'layoutWidth' with value '#android:layout_width/fill_parent').
I have found a solution by means of changing values/attrs.xml to:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<attr name="layoutWidth" format="dimension">
<enum name="fill_parent" value="-1" />
<enum name="match_parent" value="-1" />
<enum name="wrap_content" value="-2" />
</attr>
</resources>
Now, I can write in values/themes.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme" parent="android:Theme">
<item name="layoutWidth">match_parent</item>
</style>
<resources>
But the question still remain: Is it possible to refer to Android layout_width parameter from this place?
You should create attrs.xml file inside values folder and then add the below code in it:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="custom_match_parent" type="dimen">-1</item>
<item name="custom_wrap_content" type="dimen">-2</item>
</resources>
To access the above created attrs.xml add the below line inside your dimens.xml file as follows:
<dimen name="max_layout_width">#dimen/custom_match_parent</dimen>
Now to access that from a layout file you must do something like
<FrameLayout
android:layout_width="#dimen/max_layout_width"
android:layout_height="match_parent">
<!--Do what you like to do here-->
</FrameLayout>
Hope this helps! :-)
Well, this is a late response...but, for posterity and sanity, the answer can be found below and more info can be found at http://developer.android.com/guide/topics/ui/themes.html
styles.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="YourStyle" parent="#android:style/TextAppearance.Medium">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
</style>
</resources>
This should work for any parent style that uses android:layout_width, such as parent="#android:style/Widget.TextView"
Not sure if you can add this attribute somewhere in your resources or style tags, but it may help (if its legal)
xmlns:android="http://schemas.android.com/apk/res/android"
This specifies the namespace where layout_width and layout_height are defined (as well as the constants fill_parent and wrap_content).

Can a selector resource use a color defined in a style?

I'm trying to use a color defined in a stlyle in a selector but it is causing a Resources$NotFoundException.
First I added a new attribute to attr.xml:
<resources>
<attr name="unread_background" format="color" />
</resources>
Then I defined that attr value in styles.xml:
<style name="ThemeNoTitleBar" parent="android:Theme.NoTitleBar">
<item name="unread_background">#000000</item>
</style>
Then I tried to use that attr in my selector definition:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- other states snipped -->
<item android:state_selected="false"
android:drawable="?unread_background" />
</selector>
Lastly, the activity uses the ThemeNoTitleBar style theme in the manifest.
I've also tried creating a color in colors.xml and having it use the new attr but that also fails.
I'm obviously missing something but am not sure what to do to fix it. My intent is to create multiple themes and have the selector use the color in the currently selected theme.
<item android:state_selected="false"
android:drawable="?unread_background" />
this above section is wrong.
the drawable only take a reference to a drawable resource.
Please see this link. http://developer.android.com/guide/topics/resources/drawable-resource.html#StateList
Here is something, that works by me.
attrs.xml:
<attr name="color_selection" format="reference"/>
styles.xml, as child of main theme:
<item name="color_selection">#color/selection_background_inverse</item>
shape_background_selected.xml in drawable folder:
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="?attr/color_selection"/>
</shape>
your selector file, in my case: selector_background_recyclerview:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/shape_background_selected" android:state_activated="true" />
<item android:drawable="#drawable/shape_background_selected" android:state_pressed="true" /> <!-- pressed -->
<item android:drawable="#color/transparent" /> <!-- default -->
</selector>
finally, in your view's xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#drawable/selector_recyclerview_item_background"../>
Android button with different background colors Take a look onto the example. It looks like you need that.

Categories

Resources