My app with tabs has two themes. In each theme tabs have different images in selected and unselected state. How I can properly reference to image by theme?
For example. I have in themes.xml
<?xml version="1.0" encoding="utf-8"?>
<style name="LightTheme" parent="#android:style/Theme.Light">
<item name="tabShows">#drawable/ic_tab_shows_unselected_light</item>
<item name="tabShowsSelected">#drawable/ic_tab_shows_selected_light</item>
<item name="tabNews">#drawable/ic_tab_news_selected_light</item>
<item name="tabNewsSelected">#drawable/ic_tab_news_unselected_light</item>
</style>
<style name="DarkTheme" parent="#android:style/Theme.Black">
<item name="tabShows">#drawable/ic_tab_shows_unselected_dark</item>
<item name="tabShowsSelected">#drawable/ic_tab_shows_selected_dark</item>
<item name="tabNews">#drawable/ic_tab_news_selected_dark</item>
<item name="tabNewsSelected">#drawable/ic_tab_news_unselected_dark</item>
</style>
Also I have a tab_shows.xml and tab_news.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="#drawable/ic_tab_shows_selected_light"/>
<item android:state_selected="false" android:drawable="#drawable/ic_tab_shows_unselected_light" />
How I can reference to needed image in selector according to current theme?
This not work for me
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="?tabShowsSelected"/>
<item android:state_selected="false" android:drawable="?tabShows" />
In layout files this works, I mean reference to style via ?styleName
Build your style A and style B
in your case you put android:drawable="#drawable/ic_tab_shows_selected_light" instead of background (I just copied snipets from my code)
#000
<style name="styleB">
<item name="android:background">#000</item>
</style>
your theme A
<style name="Theme.A">
<item name="pageBackground">#style/styleA</item>
</style>
theme B
<style name="Theme.Blue">
<item name="pageBackground">#style/styleB</item>
</style>
in your attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="pageBackground" format="reference" />
</resources>
finally in your widget you do style="?pageBackground"
You can find your answer here
http://www.androidengineer.com/2010/06/using-themes-in-android-applications.html
Edit
(Additional information by Lukap in comments)
Define one or more themes in themes.xml and set the definitions of your styles there.
Define custom attributes, a.k.a. custom styles, in attrs.xml.
Describe what the values of your custom styles are in styles.xml.
But you will need read more about the attrs.xml
<item name="android:background">? android:attr/activatedBackgroundIndicator</item>
</style>
Instead, we are referring to the value of some other attribute – activatedBackgroundIndicator – from our inherited theme. Whatever the theme defines as being the activatedBackgroundIndicator is what our background should be.
Related
I have an app and I define to themes "A" and "B" inside the themes a define a set of styles
<resources>
<style name="Theme.A" parent="Theme.Base.AppCompat">
</style>
<style name="btnMiniPlayer" parent="Theme.A">
<item name="android:background">#drawable/image1</item>
</style>
<resources>
<style name="Theme.B" parent="Theme.Base.AppCompat">
</style>
<style name="btnMiniPlayer" parent="Theme.B">
<item name="android:background">#drawable/image2</item>
</style>
So I have in my app a property in a button
style="#style/button"
Depends of the style I need to change the image, also I set in the manifest the theme but the app is mixing the styles so for now I set the "A" like the primary theme but the app show the images from theme "B".
Any idea???
Do something like this:
<style name="button" parent="A">
<item name="android:background">#drawable/image</item>
</style>
drawable/image.xml:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false" android:drawable="#drawable/image1" />
<item android:state_pressed="true" android:drawable="#drawable/image2" />
</selector>
There are also things like:
android:state_selected="true"
I found how to answer my question, so you need to follow the next steps in order to fix it
1- Create an attribute in my case I set the name like myButton:
<declare-styleable name="def_Styles">
<attr name="myButton" format="reference" />
</declare-styleable>
2- In every Theme ("A" and "B") you have to define the item
<resources>
<style name="Theme.B" parent="Theme.Base.AppCompat">
<item name="myButton">#style/CustomButtonB</item>
</style>
<style name="CustomButtonB" parent="Theme.B">
<item name="android:background">#drawable/image2</item>
</style>
3- In the view just set the style to the correct attribute
style="?myButton"
If you change the theme in the manifest between A and B it will be work
I've seen similar questions here before, but none of them had a satisfactory answer. Basically, I want to have one layout instead of multiple ones and be able to apply themes at runtime. For example, let's take this layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="SAMPLE HEADING"
style="#style/Heading" />
</LinearLayout>
And the themes and styles are set up as follows:
<style name="AppTheme.Dark" parent="AppTheme">
<item name="android:radioButtonStyle">#style/radioButton.Dark</item>
<item name="android:checkboxStyle">#style/checkbox.Dark</item>
</style>
<style name="AppTheme.Light" parent="AppTheme">
<item name="android:radioButtonStyle">#style/radioButton.Ios</item>
<item name="android:checkboxStyle">#style/checkbox.Ios</item>
</style>
<style name="Heading">
<item name="android:typeface">sans</item>
<item name="android:textStyle">bold</item>
</style>
<style name="Heading.Dark" parent="Heading">
<item name="android:textColor">#color/red</item>
<item name="android:background">#drawable/dark_bg</item>
<item name="android:textSize">16dip</item>
</style>
<style name="Heading.Light" parent="Heading">
<item name="android:textColor">#color/black</item>
<item name="android:background">#drawable/light_bg</item>
<item name="android:textSize">17dip</item>
</style>
So, I want to be able to apply the dark and light Heading styles to that TextView by simply applying the dark or light AppTheme. And I don't want to apply those styles to all TextViews, but only specific ones. I also don't want to do this programmatically because there are way too many TextViews that would need this done.
Is there a way to do that, or do i have to create two identical XML layouts, where one uses the Heading.Light style and the other uses Heading.Dark?
First, your use of parent="..." property is incorrect.
As official docs state:
"If you want to inherit from styles that you've defined yourself, you do not have to use the parent attribute. Instead, just prefix the name of the style you want to inherit to the name of your new style, separated by a period."
So, declaring your style name as Heading.Light is enough to specify that it's parent style is Heading.
Now to your question. Create a res/values/attrs.xml file:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="myTextViewColor" format="reference|color" />
</resources>
Then in your styles.xml you would declare your theme as follows:
<style name="AppTheme">
<!--parent style. could be overriden by Dark and Light theme -->
</style>
<style name="AppTheme.Dark">
...
<item name="myTextViewColor">#color/red</item>
</style>
<style name="AppTheme.Light">
...
<item name="myTextViewColor">#color/black</item>
</style>
<style name="Heading">
<item name="android:typeface">sans</item>
<item name="android:textStyle">bold</item>
<item name="android:textSize">16dip</item>
</style>
Now when you apply
<TextView ... style="#style/Heading" android:textColor="?myTextViewColor />
everything should work just fine. Just make sure you apply AppTheme.Light or AppTheme.Dark theme in your app (as AppTheme parent theme would not know the value of your custom attribute).
Edit: Also, as user496854 suggested, there's another simple workaround.
Declare headingStyle attr as a reference:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="headingStyle" format="reference" />
</resources>
Then in our AppTheme.Dark and AppTheme.Light styles we would point to a corresponding heading style:
<style name="AppTheme.Dark">
...
<item name="headingStyle">#style/Heading.Dark</item>
</style>
<style name="AppTheme.Light">
...
<item name="headingStyle">#style/Heading.Light</item>
</style>
I would suggest you to crate a class that extends TextView and apply your style in it. Use this textView where you want textview with this them and simple TextView where you don't need.
I have this theme in values/styles.xml, that I apply to my whole application.
<!-- Base application theme. -->
<style name="AppTheme" parent="#style/_AppTheme">
<!-- a bunch of things... -->
<item name="android:textColorHighlight">#9999cc00</item>
<!-- a bunch of things... -->
</style>
<style name="_AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"/>
Then in values-v9
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppTheme" parent="#style/_AppTheme">
<item name="android:textSelectHandleLeft">#drawable/apptheme_text_select_handle_left</item>
<item name="android:textSelectHandleRight">#drawable/apptheme_text_select_handle_right</item>
<item name="android:textSelectHandle">#drawable/apptheme_text_select_handle_middle</item>
</style>
</resources>
And finally in values-v11
<?xml version="1.0" encoding="utf-8"?>
<!-- Generated with http://android-holo-colors.com -->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppTheme" parent="#style/_AppTheme">
<item name="android:dropDownSpinnerStyle">#style/SpinnerAppTheme</item>
<item name="android:listChoiceBackgroundIndicator">#drawable/apptheme_list_selector_holo_light</item>
<item name="android:activatedBackgroundIndicator">#drawable/apptheme_activated_background_holo_light</item>
<item name="android:textColorHighlight">#9999cc00</item>
<item name="android:textSelectHandleLeft">#drawable/apptheme_text_select_handle_left</item>
<item name="android:textSelectHandleRight">#drawable/apptheme_text_select_handle_right</item>
<item name="android:textSelectHandle">#drawable/apptheme_text_select_handle_middle</item>
</style>
</resources>
All of the drawables are in their respective folder.
This has no effect in changing the text select handle in any part of the application.
Is this because of the AppCompat library use maybe?
How do I repair?
Using this link
http://android-holo-colors.com/
The worst part here was to find the "name" for this item and how it is called inside the theme. So I looked through every drawable in the android SDK folder and finally found the drawables named "text_select_handle_middle", "text_select_handle_left" and "text_select_handle_right".
So the solution is simple: Add these drawables with customized design/color to your drawable folder and add them to your theme style definition like:
<style name="MyCustomTheme" parent="#style/MyNotSoCustomTheme">
<item name="android:textSelectHandle">#drawable/text_select_handle_middle</item>
<item name="android:textSelectHandleLeft">#drawable/text_select_handle_left</item>
<item name="android:textSelectHandleRight">#drawable/text_select_handle_right</item>
</style>
I've tried to let the SampleTabsStyled demo from the ViewPagerIndicator change the color of the text of the currently selected tab without success.
However, the SampleTitlesStyledTheme demo does change its text color when switching between titles/tabs.
When looking inside the styles xml:
<resources>
...
<style name="CustomTitlePageIndicator">
<item name="android:background">#18FF0000</item>
<item name="footerColor">#FFAA2222</item>
<item name="footerLineHeight">1dp</item>
<item name="footerIndicatorHeight">3dp</item>
<item name="footerIndicatorStyle">underline</item>
<item name="android:textColor">#AA000000</item>
<item name="selectedColor">#FF000000</item>
<item name="selectedBold">true</item>
</style>
...
<style name="CustomTabPageIndicator" parent="Widget.TabPageIndicator">
<item name="android:background">#drawable/custom_tab_indicator</item>
<item name="android:textAppearance">#style/CustomTabPageIndicator.Text</item>
<item name="android:textColor">#FF555555</item>
<item name="android:textSize">16sp</item>
<item name="android:divider">#drawable/custom_tab_indicator_divider</item>
<item name="android:dividerPadding">10dp</item>
<item name="android:showDividers">middle</item>
<item name="android:paddingLeft">8dp</item>
<item name="android:paddingRight">8dp</item>
<item name="android:fadingEdge">horizontal</item>
<item name="android:fadingEdgeLength">8dp</item>
</style>
<style name="CustomTabPageIndicator.Text" parent="android:TextAppearance.Medium">
<item name="android:typeface">monospace</item>
</style>
...
</resources>
I see that the SampleTitlesStyledTheme demo uses the CustomTitlePageIndicator style, which defines a selectedColor item. So (perhaps naively) I thought to add
<item name="selectedColor">#FF000000</item>
to the style the SampleTabsStyled demo is using, CustomTabPageIndicator, but, alas, that didn't work.
The question seems obvious, but I'll ask anyway: is there a way (using the present styles xml) to let the currently selected text of a tab in the SampleTabsStyled demo have a different color than the other tabs? If so, how?
EDIT
Oh, and I'm using this in combination with ActionBarSherlock, in case that is important...
Assuming you don't mind creating an extra xml, first try include the attribute android:textColor in your CustomTabPageIndicator.Text (or CustomTabPageIndicator) like this:
<style name="CustomTabPageIndicator.Text" parent="android:TextAppearance.Medium">
<item name="android:textColor">#drawable/tab_text_color</item>
...
</style>
where tab_text_color.xml is put under res/drawable folder:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_selected="true"
android:color="#color/text_tab_selected" />
<item
android:state_selected="false"
android:color="#color/text_tab_unselected" />
</selector>
Finally, just define the two colors #color/text_tab_selected and #color/text_tab_unselected in your color resource file colors.xml located in res/values folder (create one if it does not exist already). For example:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="text_tab_selected">#FF000000</color>
<color name="text_tab_unselected">#FF555555</color>
</resources>
Try this
Simplest way
<android.support.design.widget.TabLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabTextColor="#color/White"
app:tabSelectedTextColor="#color/Blue"
app:tabIndicatorColor="#color/Yellow"
app:tabMode="fixed"
app:tabGravity="fill"/>
Don't forgot to add this Dependency
compile 'com.android.support:design:23.1.1'
Let's say I have multiple styles.xml files (with different names of course) for themes. Is it possible to choose which file the app should pull from?
White style:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="mybutton">
<item name="android:layout_width">45dp</item>
<item name="android:layout_height">fill_parent</item>
<item name="android:textColor">#202020</item>
<item name="android:textSize">20dp</item>
<item name="android:textStyle">bold</item>
<item name="android:background">#drawable/white_btnbg</item>
</style>
...
Black style:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="mybutton">
<item name="android:layout_width">45dp</item>
<item name="android:layout_height">fill_parent</item>
<item name="android:textColor">#FFFFFF</item>
<item name="android:textSize">20dp</item>
<item name="android:textStyle">bold</item>
<item name="android:background">#drawable/black_btnbg</item>
</style>
...
So then, in my layout xml all my button's styles would be set to "mybutton" and depending which theme the user chose it would pull from the coordinating file.
Since it isn't possible to change a view's style at runtime is it possible to do this? Or is there a better way (i'm sure there is) to change styles?
Use multiple styles with different names. Then you can set the backGround programmatically:
Button b = new Button(this);
b.setBackgroundResource(R.drawable.blabla);