I'm trying to work out how to organize an android application that will have multiple themes. here's a simplified example of my problem,
2 themes, "light" and "dark",
within each theme, two text colors: "enabled" and "disabled"
now the problem is that when i define my TextView, i don't want to call out "light" or "dark" there, i want to just specify the theme at the application level and have it applied. basically, i want CSS selectors. i want to be able to define my theme like,
<style name="Light.enabled" .../>
<style name="Light.disabled" .../>
and my text view like,
<TextView style="#style/.enabled" .../>
<TextView style="#style/.disabled" .../>
and have it apply "enabled" or "disabled" based on whether i've called out "light" or "dark" at the application level.
this page,
http://www.androidengineer.com/2010/06/using-themes-in-android-applications.html
shows an app that
defines a style, say "light.enabled"
#000000
defines an attribute reference, say "enabled"
defines a style (theme) item like,
#style/light.enabled
uses the attr to define the style in the view,
this is what i want, but it doesn't work for me. the only diff is that i'm using an appwidget. the author sets the theme on the activity. the only place i can set it is Context.setTheme(), and at the "application" tag in the manifest. neither of which seems to make a difference.
You can't apply themes to app widgets. You'll just need to have different XML that uses different styles.
Also, it is confusing when you talk about light vs. dark and enabled vs. disabled as similar things. They are very different in the platform.
Light and dark are actual "themes" as the platform defines it, which is a set of default values for resource attributes, rooted off of android:style/Theme. These are changed with android:theme in the manifest or setTheme() in the API.
enabled and disabled are states. They are used with StateListDrawable (via tag in drawable/) or ColorStateList (via tag in color/) to pick a drawable/color based on the enabled state.
For example here is a color that changes based on state:
https://android.googlesource.com/platform/frameworks/base/+/master/core/res/res/color/primary_text_dark.xml
And here is a drawable that changes based on state:
https://android.googlesource.com/platform/frameworks/base/+/master/core/res/res/drawable/btn_default.xml
If you are trying support multiple themes in application.
Define theme in values/styles.xml
<style name="AppTheme" parent="Theme.AppCompat.Light">
#drawable/ic_mode_comment_white_24dp
...
#drawable/ic_subject_black_24dp
define colors in colors.xml
<resources>
<color name="colorPrimary">#FF9800</color>
</resources>
switch themes in activity runtime
public abstract class BaseActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
if (PreferenceManager.getDefaultSharedPreferences(this)
.getBoolean("pref_dark_theme"), false)) {
setTheme(R.style.AppTheme_Dark);
}
super.onCreate(savedInstanceState);
}
}
follow this articles part1 and part2
I add many more themes to the android app. But work only if-else statements.
My code:
if (sharedPreferences.getString("color_option", "Blue").equals("Blue")) {
setTheme(R.style.RedTheme);
} else {
setTheme(R.style.BlueTheme);
}
Next Step
if (sharedPreferences.getString("color_option", "Blue").equals("Blue")) {
setTheme(R.style.RedTheme);
} else if(sharedPreferences.getString("color_option", "Blue").equals("Blue")) {
setTheme(R.style.BlueTheme);
} else {
setTheme(R.style.HTheme);
}
Both Code does not work only Selected two themes not selected the third theme (Not Work). I add multiple or more themes.
Related
I've added dark theme support for my application using 2 different themes declared in styles.xml.
On official android developer site:
In order to support Dark theme, you must set your app's theme (usually
found in res/values/styles.xml) to inherit from a DayNight theme
and this is what I've done. I've also created colors-night.xml to avoid modifying colors that cannot be modified in styles.xml by coding and this works too: when dark mode is activated from device system, colors changes automatically.
At this point, I was wondering which is the best way to implements dark theme: creating 2 different themes, using colors-night (and drawable-night) or a combination of these 2 ways?
First up is the youtube video below pretty much tells you what the current best practices are with regards to theming.
https://www.youtube.com/watch?v=Owkf8DhAOSo
They talked about splitting your styles into
themes.xml -> theme related styles
styles.xml -> component related styles
type.xml -> text appearances styles
All your colors should then be in one colors.xml which lives in values.
You will then have the following structure:
values/themes.xml
values/colors.xml
values/type.xml
values/styles.xml
values-night/themes.xml
In practice, I find that it is still hard to contain all the colors in just one colors.xml. I still create values-night/colors.xml as some colors don't necessarily fall into a style.
See this in practice in this repo. Observer that Google themselves didn't follow their point on just using one colors.xml.
https://github.com/material-components/material-components-android/tree/master/material-theme-builder
This is the home screen of my app. I have used Drawable and Color resources in the design. Now I want to have multiple color sets (for the parts with cyan color) so user can change them at run time. I searched a lot, but they don't fit my case.
Note that I want just the cyan colored parts to change. I know I can change all the TextView styles using style attribute, but I just need certain views get certain drawables or colors as background.
I found a solution here but I cannot use it because it needs the min sdk higher than 21 while mine is 16.
Home screen
You can easily set theme like this:
public void onCreate(Bundle savedInstanceState) {
setTheme(R.style.your_theme);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity)
}
Define your style in values/styles.xml like so:
<style name="AppTheme.MyTheme" parent="AppTheme.NoActionBar">
<item name="colorPrimary">#color/primaryColorCyan</item>
<item name="colorPrimaryDark">#color/primaryDarkColorCyan</item>
<item name="colorAccent">#color/secondaryColorCyan</item>
</style>
And then call setTheme(R.style.MyTheme) before setContentView() in onCreate() method. setTheme introduced in API LEVEL 1.
I have to declare some base values for my App (like windowNoTitle).In some activities the Theme.AppCompat.Light theme is needed cause of transparent background images. They need a white background but `` In others the Theme.AppCompat theme will be used for styling.
My App uses androidx.appcompat.widget.Toolbar. So I need to extend a Compat theme. I can't apply the default values as parent and apply the style via theme name.
How to apply the default values to both themes but not repeat my self. Is it possible to declare "style variables"?
Thanks in advance
My calculator app consists of 30 buttons. I want to provide themes for the calculator keypad. A theme changes button background (gradients, not image backgrounds) and font. Some themes have the same color for all buttons while some have a color for numbers, another color for operators and so on.
The color change is using selectors from res/drawable/*.xml
How do I change the theme via the code?
Hopefully avoiding typing:
button.setBackground(Drawable background);
button.setTypeface(font);
30 times. And if I have 5 themes, then 30 * 5 * 2 = 300 lines of codes!!
I'm new to this and if there is no other way I'll go with the 150 lines.
Also how do I save the user theme selection? Using preferences?
You can create a custom XML theme which will change all of your XML components. After creating a new theme, go into the Android Manifest file and change the theme. For example:
<activity
android:name="com.myapp.MyActivity"
...
android:theme="#style/MyCustomTheme" />
To create the theme, go to res/values/themes.xml and create a new theme with an identifier:
<resources>
...
<style name="MyCustomTheme" parent="android:style/Theme">
<item name="android:textColorPrimary">#ffff0000</item>
</style>
...
</resources>
By using this method, you can create an extensive library of different themes and change to what theme you want.
NOTE: This is not just for changing the background, but it can also be used to change the theme of the buttons. Visit this website for more information:
http://janrain.com/blog/introduction-to-android-theme-customization/
EDIT: As that user commented, it is possible that you can put the function to change the theme of the button in a for() loop.
For your case, I have derived this from the link above. It will change the texture of the buttons in your XML file rather than in Java.
"Using a Custom Nine-Patch With Buttons
A nine-patch drawable is a special kind of image which can be scaled in width and height while maintaining its visual integrity. Nine-patches are the most common way to specify the appearance of Android buttons, though any drawable type can be used.
Example nine-patch PNG.
Notice the one pixel black lines around the edge, they control the scaling of the image.
Save this bitmap as MyApplication/res/drawable/my_nine_patch.9.png
Define a new style (you can define the new style in the same file that you defined your custom theme from Creating a Custom Android Theme above) …:
<resources>
...
<style name="MyCustomButton" parent="android:Widget.Button">
<item name="android:background">#drawable/my_nine_patch</item>
</style>
...
</resources>
Apply the new button style to the buttonStyle attribute of your custom theme:
<resources>
...
<style name="MyCustomTheme" parent=...>
...
<item name="android:buttonStyle">#style/MyCustomButton</item>
</style>
...
</resources>
Now the buttons in the activities your theme is applied to have custom images. However, you may notice that they don’t change appearance when selected. Read Selector Drawables below for an introduction to using multiple drawables to define one drawable that changes based on state."
From here, you can change certain components of the theme (such as the button texture as an image).
After you have a theme that looks good, apply it in the Android Manifest as I mentioned above.
I will FURTHER edit this if it still does not answer your question.
I have a couple custom preference items -- one that displays a swatch of the currently selected color, and another one that displays a thumbnail.
I have a custom layout for these that matches up very well, and have found that I can make the text appearance match by using android:textAppearance="?android:attr/textAppearanceLarge" as part of the TextView's xml. The problem is, while these generally look fine, they must not be the appearance the 'official' preferences use, since the colors end up wrong on some devices. In particular I'm porting my application to the Nook Color, and it uses a light grey background and black text color on the preference screen instead of black background/light grey text. My text color in this situation stays the same, but the rest of my layout is themed appropriately.
I'm really unsure what I'm supposed to do here to make my text match up with the 'official' theme. Should I be using obtainStyledAttributes and running though my layout to set things? The tutorials I've seen on using that so far have been really baffling, and it seems like there must be a textAppearance or style I can set in the XML to fix this.
You've to define your own application theme which inherits from the official theme you want. Actually, you can just define a theme MyTheme extending the Theme.Light for example.
Create an res/values/styles.xml file like that:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyTheme" parent="#android:style/Theme.Light">
</style>
</resources>
Then, you just have to apply your theme using the android:theme attribute of the application entity of your AndroidManifest.xml:
<application android:theme="#style/MyTheme">
[...]
</application>