I may have a flawed understanding of how themes work in android, so I'm just gonna say what I want to do, and someone can tell me why I'm wrong:
I'd like my application to switch between a dark and a light theme, so I've declared two themes. The theme switching works fine, the problem arises when I'd like to add an attribute that presumable doesn't exist:
<style name="AppThemeDark" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#000</item>
<item name="colorPrimaryDark">#000</item>
<item name="colorAccent">#000</item>
<item name="colorBackground">#000</item>
...
</style>
Which yields the result: No resource found that matches the given name: attr 'colorBackground'.
So I know that one of two things is at play here:
I somehow, somewhere need to define colorBackground, or..
I cannot add any new attributes and must work with the ones I am given, which seems odd to me, but hey, what do I know.
I want both of my themes to have a 'colorBackground' so that I can set the application's views' backgrounds to the corresponding theme. a light background for the light theme and a darker background for the dark theme. Ideally something like:
<RelativeLayout>
....
android:background="?attr/colorBackground"
....
</RelativeLayout>
There may be a specific attribute that is made to do this specifically, but I do not know it.
So what am I doing wrong?
Related
I have been learning MDC from google code lab, and it is a well designed application to know how material design works. However, in a particular section they showed how to use dark theme. The did it by changing the theme attributes from style.xml. Being resourceful, I have been trying to learn how to use multiple theme and interchange them runtime.
For this reason I avoided their hard-coded way and tried to inherit the base theme and put changes according to my need. Below I am putting some changes in the theme file
<!--Dark Theme style !-->
<style name="Theme.Shrine.Dark" parent="Theme.Shrine">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/darkColorPrimaryDark</item>
<item name="colorPrimaryDark">#color/darkColorPrimaryDark</item>
<item name="colorAccent">#color/darkColorAccent</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">false</item>
<item name="android:textColorPrimary">#color/darkTextColorPrimary</item>
<item name="colorControlActivated">#color/darkColorControlActivated</item>
<item name="toolBarStyle">#style/Widget.Shrine.Toolbar.Dark</item>
<item name="appBackGroundColor">#color/darkBackgroundColor</item>
</style>
There are some changes but they are irreverent to my problem, so I am not going to add them here. Anyway, with changes in my style file app looks something like this
Everything is expected except for icon colour in toolbar. So I check into the code and find every icon colour is referenced from the their respective from drawable file with android:tint="#color/toolbarIconColor" and in color.xml toolbarcolor is <color name="toolbarIconColor">#color/textColorPrimary</color>
It shows wrong color in dark mode, in this case how can I show yellow color in dark mode. I have changed textColoeSecondary from base theme of dark theme but it didn't work
Firstly, you need to remove hard reference of colour from every drawables which reflect different colours depending on app theme. So, add attrs.xml in your values directory. and add the reference name for icon colour such as this one
<attr name="toolbarIconColor" format="reference"/>
Secondly, add two different colour for two themes. For example, for normal theme <color name="toolbarIconColor">#color/textColorPrimary</color> and for dark one use <color name="darkToolbarIconColor">#FFCF44</color>
Finally, go to your style.xml file and make this change to hook up with the reference we have added in attrs.xml file, like this one for normal theme <item name="toolbarIconColor">#color/toolbarIconColor</item> and <item name="toolbarIconColor">#color/darkToolbarIconColor</item>
I get this as one of my colors generated by the Material Design Color Platte.
But in this image:
I don't see colorPrimaryLight anywhere. What is it used for and how do I declare it? Do declare it like this in my style?:
<item name="colorPrimaryLight">#color/colorPrimaryLight</item>
Or do I declare it in a different way? And what is it used for?
By default, the statusBarColor is set to colorPrimaryDark. If you want to use colorPrimaryLight for the status bar you need to set android:statusBarColor to android:colorPrimaryLight.
https://developer.android.com/training/material/theme.html
in your resources file put:
<color name="colorPrimaryLight">#D1C4E9</color>
in your styles file put:
<item name="colorPrimaryLight">#color/colorPrimaryLight</item>
TL;DR: colorPrimaryLight is one of several colors identified as part of the Material palette that is not actually mapped to a Theme attribute in Android. The guidelines recommend using it in several areas such as a TabLayout backgrounds.
I cannot find an authoritative source about using this attribute in Android apps, but it seems that Material defines a large number of colors, as shown on this helpful page, but not all of them are mapped to Android Theme attributes. For instance, if you create a brand new single-Activity project in Android Studio and modify styles.xml as shown below:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<!-- THIS THEME ATTRIBUTE IS NOT FOUND -->
<item name="colorPrimaryLight">#color/colorPrimary</item>
</style>
</resources>
The colorPrimaryLight attribute is not found by the compiler.
Therefore if you wanted to use it in your application you would presumably have to explicitly link to a color.xml resource. This seems to negate the benefit of the Theme system somewhat, but perhaps I am missing a trick.
I have an app with a few different Activities. The different activities have different styled buttons, texts, etc... I've set up all the components to have various styles based on their location/Activity. (Eg. style="#style/MainMenuActionBarTitle, or style="#style/MainMenuActionBarTagLine). These styles set the background (Drawable, MipMap, or Color), textColor, etc...
The app will be offering some theme packs which change the colors of these various components throughout the application, and I was hoping there was a way to have Styles with the same name, but different values based on the Theme of the app. This way I can just change the Theme whenever the Activity is loaded to whatever Theme the user has chosen.
There's some good info here on how to change the standard widget look & feel using Themes, but that changes the look and feel for the standard-un-styled widgets.
Is there a way to accomplish this using Themes, or is this the wrong direction altogether? Is there a better/easier route?
Edit: After doing more research and more fiddling, I've realized what I want to do isn't far off from how I can accomplish this. What I want to do is to actually change component Styles when I set the Theme of the Activity.
One solution I've discovered is to use attributes which the Theme can point to different Styles.
attrs.xml
<resources>
<!-- Attributes referencing whatever style the theme needs to set up. -->
<attr name="main_menu_button_style_play" format="reference" />
</resources>
themes.xml
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- App specific attributes -->
<item name="#attr/main_menu_button_style_play">#style/MainMenu.Button.Play</item>
</style>
<!-- Blue application theme. -->
<style name="AppTheme.Blue" parent="AppTheme">
<!-- App specific attributes -->
<item name="#attr/main_menu_button_style_play">#style/MainMenu.Button.Play.Blue</item>
</style>
</resources>
styles.xml
<style name="MainMenu.Button.Play">
<item name="android:background">#f76d3c</item>
<item name="android:text">PLAY</item>
</style>
<style name="MainMenu.Button.Play.Blue">
<item name="android:background">#2ca8c2</item>
</style>
activity.xml
<Button android:id="#+id/main_play_button"
style="?attr/main_menu_button_style_play"/>
This works really well, and allows me to set the Theme in the Activity.onCreate() method.
The only annoying problem I have with this solution is that Android Studio complains that the Button is missing the layout_width and layout_height even though they're defined in the Style. I guess it doesn't follow the attribute reference back through the chosen Theme.
Another approach which is what I ended up using was to more heavily use the attributes. Creating attributes for all the properties values I want to change between themes. So, instead of main_menu_button_style_play which defines the style reference, I used main_menu_button_play_background. This approach is the same amount of work as simply specifying a style because themes can inherit, but the IDE understands it.
I am trying to get rid of my actiobars and use toolbar to update my app. I am not making my apps for 5.0 yet, so no other material goodness.
From following another post I made my themes.xml look like this:
<style name="AppTheme.Base" parent="Theme.AppCompat">
<item name="colorPrimary">#color/mycolorprimary</item>
<item name="colorPrimaryDark">#color/mycolorprimarydark</item>
<item name="android:windowNoTitle">true</item>
<item name="windowActionBar">false</item>
</style>
The first issue I am having is that "Style" is throwing this error:
Element Style must be declared
Theme vs Style
So what exactly is the difference? Well they are both declared in exactly the same way (which you already know), the difference comes in how they’re used.
Themes are meant to be the global source of styling for your app. The new functionality doesn’t change that, it just allows you to tweak it per view.
Styles are meant to be applied at a view level. Internally, when you set style on a View, the LayoutInflater will read the style and apply it to the AttributeSet before any explicit attributes (this allows you to override style values on a view).
Values in an attribute set can reference values from the View’s theme.
Themes are global, styles are local.
From theme-vs-style
I would recomend a read at the above link.
Each "layout" I set a white background and "Manifest" I set Theme.Light.
Still receives a gray background instead of white. Why?
Edit:
Manifest.xml
android:theme="#android:style/Theme.Light.NoTitleBar">
Layout
android:background="#android:color/white"
Theme.Light does not mean that it will be white. It just means that it will be light, not dark :P This is not theme.white.
Each device manufacturer can customize Android OS on his phone for example to preferred colors and look & feel. In particular he can define styles for his Android implementation - Light and dark. Thanks to that your app may look differently on various devices, however it will always fit the style used on this device (every app in style Theme.Light will have grey background on this device, unless you set android:background="#android:color/white" )
Your device's manufacturer defined style Theme.Light as style with grey background.
Hope that I am clear - otherwise do not hesitate to ask
I had the same issue until I changed #android:color/white to explicit android:background="#FFFFFF". Weird though...
Since it's an old question this might have another solution already but anyway one can just enter the AppTheme style tag in styles.xml, you can do so by pressing the ⌘cmd key and clicking on your theme declaration in the manifest.
Over there add this line with your preferred color -
<item name="android:windowBackground">#color/white</item>
This line basically overrides the theme's default background value.
Example -
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:colorControlActivated">#color/black</item>
<item name="android:windowBackground">#color/white</item>
</style>