In my application I have different Themes - one dark and one bright theme. Each theme requires his own icon set.
How do I apply it to the theme? Is there something like a special folder like for icons with different sizes ?
The following serves as a hint...
I suppose this may help: http://developer.android.com/reference/android/R.attr.html#icon
Lets say you have the following themes...
<style name="MyTheme.Dark">
...
</style>
<style name="MyTheme.Light">
...
</style>
You can add <item name="android:icon"></item> to each theme and supply each one with their own drawable icon. Then to get the respective drawables in your layout or what have you, you need to make use of ?android:attr/icon.
So your layout may end up looking something like...
<View
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="?android:attr/icon"/>
If you're unsure about what the ?android:attr/icon part exactly means, read http://developer.android.com/guide/topics/resources/accessing-resources.html#ReferencesToThemeAttributes.
Is there something like a special folder like for icons with different sizes ? (up to my knowledge) NO
no such default folder exist which you can use for Themes.
You need to do it programmatically.
Save the theme info in your Shared Preferences.
and at time of loading the view you can set your desired themed drawable.
Related
Anyone can help me?
I'm developing the Light and Dark theme function in the android app, everything goes fine, but the background of Recyclerview shows incorrectly.
The root background of xml file is White color and I didn't set background for recyclerview in xml. However, after changing from Light to Dark or Dark to Right=> background of recyclerview automatically change to a strange color(this color didn't see in my color.xml resource). I tried to set background of Recyclerview to #null or transparent in code and xml file as well but the background of recyclerview didn't remove that strange color.
So anyone knows exactly the reason why, please help me and much appreciated. Thanks
enter image description hereenter image description here
I am guessing you are using the DayNight Theme. If so you should have to themes.xml folder in res, one is called as mentioned and the other is with the extension (night). There you can define a color in both xml files. It has the same name but different color values like this:
<style name="AppTheme" parent="Theme.AppCompat.DayNight">
<item name="colorPrimaryDark">#ffffff</item> <!-- you normally shouldn't hardcode color -->
</style>
The same for your folder (night):
<style name="AppTheme" parent="Theme.AppCompat.DayNight">
<item name="colorPrimaryDark">#000000</item> <!-- you normally shouldn't hardcode color -->
</style>
The idea is to have one attribute name that contains 2 colors and takes the correct one if needed. For futher understanding I suggest to take a look at this reference to get more familiar with Themes and Styles. Now you set up your Day and Night files properly, you can implement it by using it in your recyclerView as follows:
android:background="?attr/colorPrimaryDark"
Another tip is to make custom colors in multiple colors.xml files to make them for more unique use. In this case colorPrimaryDark effect your whole app. It is also suggested to modify layouts and the visuals of widgets to take effect only on those. (e.x. your recyclerView). In my app I used colorPrimaryDark for all Background (that should be same for more clean design). I think you get the keypoint. Take a look around the net and this forum and you will find your final design strategy. Cheers! :)
I'm not sure what is the best way to develop interfaces in Android.
is it better to clean the layout file by moving inline attributes to a style file? As far as I know, in HTML it is better to use classes and ids inside HTML, and use them in style.css file. What about android?
I found this, maybe it helps someone else.
When to use Styles
The first problem we must address is a simple one: when should you use a style instead of inline attributes?
Rule #1: Use styles when multiple Views are semantically identical.
This rule is best illustrated with a few examples:
You're creating a calculator. Each button should look the same, so it makes sense to create a `CalculatorButton` style.
You've got a couple screens with multiple text formats - say, headers, subheaders, and text. You can unify their look by creating `Header`, `Subheader` and `Text` styles.
You've got thumbnails all over your app. You want them all to look the same. The `Thumbnail` style is born.
The common thread in all these examples is that these Views are not just using the same attributes - they play the same role across the app. Now, when you want to tweak the look/feel of any of these Views, you can just edit the style and change them all at once. It saves you time, effort and keeps your Views consistent.
Want to save even more work? Use resource references!
Rule #2: Use references within styles when appropriate.
You could define a style this way:
<style name="MyButton">
<item name="android:minWidth">88dp</item>
<item name="android:minHeight">48dp</item>
</style>
What if you wanted minWidth to vary based on screen size? You could just duplicate the style once per screen size (say, sw600dp and sw900dp), but then you're having to duplicate the minHeight attribute as well. What if you want both attributes to change? Suddenly you've got tons of MyButtons defined everywhere, each one duplicating all other attributes. It's a recipe for disaster; it's so easy to forget to change one attribute in one of the many copies.
Styles are just an alias to a series of attributes. It's a lot easier to just define the style like this:
<style name="MyButton">
<item name="android:minWidth">#dimen/button_min_width</item>
<item name="android:minHeight">#dimen/button_min_height</item>
</style>
Now you can just modify a single attribute for each resource qualifier. It's absurd to think about duplicating a layout just to change, say, the width of one View in portrait vs. landscape. You'd use a dimension for that. The same applies for styles.
I don't mean to imply you should always use resource references in styles; just that you should use it if you need multiple values switched on resource qualifiers.
This isn't to say that sometimes you won't need to duplicate a style across resource qualifiers, but you can keep it to a minimum. Usually the only reason to do so is because of platform changes (e.g., the change from paddingLeft and paddingRight to paddingStart and paddingEnd).
Multiple Styles
It would be wonderful if you could apply multiple styles to a single View, like CSS.
You can't. Sorry.
But you can, in a couple of cases, get an approximation of multiple styles.
Rule #3: Use themes to tweak default styles.
Themes provide ways of defining the default style of many standard widgets. For example, if you want to define the default button for the app, you could do this:
<style name="MyTheme">
<item name="android:buttonStyle">#style/MyButton</item>
</style>
If you're just tweaking the default style, the only tricky part is figuring out the parent of your style; you want it to match the appropriate theme for the device, but that varies based on OS version.
If you're using an AppCompat theme, you should use their styles as the parent since they handle differences across platforms as well. For example, they have a Spinner style:
<style name="MySpinner" parent="Widget.AppCompat.Spinner" />
If the style doesn't exist in AppCompat (or you're not using it), the problem is a bit trickier, since you need the parent to switch based on the theme. Here's an example of a custom Button style that uses Holo normally, but Material when appropriate.
You'd put this in /values/values.xml:
<style name="ButtonParent" parent="android:Widget.Holo.Button />
<style name="ButtonParent.Mine">
<item name="android:background">#drawable/my_bg</item>
</style>
Then, in /values-v21/values.xml:
<style name="ButtonParent" parent="android:Widget.Material.Button />
Setting up the correct parent will ensure consistency with both your app and the platform.
If you truly want to define all necessary attributes (instead of just tweaking the defaults), you could skip parenting entirely.
Rule #4: Use text appearance when possible.
TextAppearance allows you to merge two styles for some of the most commonly modified text attributes. Take a look at all your styles: how many of them only modify how the text looks? In those cases, you could instead just modify the TextAppearance.
First, you need to define your TextAppearance:
<style name="MyTextAppearance" parent="TextAppearance.AppCompat">
<item name="android:textColor">#0F0</item>
<item name="android:textStyle">italic</item>
</style>
Notice how I've set a parent - text appearances won't merge, so you need to make sure to define all attributes. You can use any appropriate TextAppearance as the parent.
Now you can use it in a TextView:
<TextView
style="#style/MyStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="#style/MyTextAppearance" />
Notice that I can still apply a style to this TextView, getting me a whopping TWO styles for one view! Not as good as true multiple styles, but I'll take what I can get.
You can use TextAppearance in any class that extends TextView. That means that EditText, Button, etc. all support text styling.
Common Pitfalls
I've explained all the times when I use styles. Unfortunately, it is easy to abuse styles in ways that will hurt you in the long run. Here's a few anti-patterns to avoid.
Rule #5: Do NOT create a style if it's only going to be used once.
Styles are an extra layer of abstraction. It adds complexity. You have to lookup the style to see the attributes they apply. As such, I see no reason to use them unless you're going to use the style in multiple places.
Which would you rather see when you open up a layout: This?
<TextView style="HelloWorldTextView" />
Or this?
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
It's so easy to create a style later if you need to do so. Don't plan ahead too much.
Rule #6: DO NOT create a style just because multiple Views use the same attributes.
The main reason to use styles is to reduce the number of repeated attributes, right? Why not just use a style whenever multiple Views use the same attributes?
The problem with this attitude is that those Views, if they are not used in the same context, may eventually want to differ in how they look. And at that point, your base style becomes difficult to edit without unintended side effects.
Think about this scenario: you've got a few TextViews that the same text appearance and background. You think, "hey, I'll create a style, that'll cut down on code duplication." Everything is hunky dory at first, but eventually you want to tweak how some of the TextViews look. The problem is, by now that style is used all over the place, so you can't edit it without some collateral damage.
Fine, you say - I'll just override the style directly in the layout XML. Problem solved. Then it happens again. And again. Eventually that style is meaningless because you're having to override it everywhere. It ends up adding extra work instead of making life easier.
That's why I specified in rule #1 that you should use styles when the Views are semantically identical. This ensures that when you change a style, you really do want every View using the style to change.
Implicit vs. Explicit Parenting
Styles support parenting, wherein a child style adopts all attributes of a parent style. It would be rather limiting if they did not.
Suppose I want every Button in the app to look the same, so I make a ButtonStyle. Later, I decide half the Buttons should look slightly different - with parenting, I can just create ButtonStyle.Different, getting the base style + the tweaks.
It turns out there are two ways of defining parents, implicitly and explicitly:
<!-- Our parent style -->
<style name="Parent" />
<!-- Implicit parenting, using dot notation -->
<style name="Parent.Child" />
<!-- Explicit parenting, using the parent attribute -->
<style name="Child" parent="Parent" />
Simple enough, right? But what do you think happens here, when we define parents with both methods?
<style name="Parent.Child" parent="AnotherParent" />
If you answered that the style has two parents, you are wrong. It turns out that it only has one parent: AnotherParent.
Each style can only have one parent, even though there are two ways to define it. The explicit parent (using the attribute) takes precedence. This leads me to the next rule:
Rule #7: DO NOT mix implicit and explicit parenting.
Mixing the two is a recipe for confusion. Suppose I have this layout:
<Button
style="#style/MyWidgets.Button.Awesome"
android:layout_width="match_parent"
android:layout_height="match_parent" />
But it turns out that my style is defined thus:
<style name="MyWidgets.Button.Awesome" parent="SomethingElse" />
Even though it looks like my Button is based on MyWidgets.Button, it's not! The style name is misleading and the only way to discover that is to do extra work and dig into your style files.
The common temptation is to keep using dot notation with explicit parenting so that your styles look hierarchically related:
<style name="MyButton" parent="android:Widget.Holo.Button" />
<style name="MyButton.Borderless" parent="android:Widget.Holo.Button.Borderless" />
Object-oriented styles! They look so pretty, right? But looks are all you're getting - an illusion that styles are related when they are not. The deception is that MyButton.Borderless is related to MyButton, but they have nothing in common! Let's remove the confusion by removing the dots from the name:
<style name="MyButton" parent="android:Widget.Holo.Button" />
<style name="MyBorderlessButton" parent="android:Widget.Holo.Button.Borderless" />
I lose out on the hierarchy looking pretty, but I gain a lot of utility in code.
Styles vs. Themes
Styles and themes are two different concepts. While styles apply to a single View, themes are applied to a set of Views (or to a whole Activity).
For example, suppose you are using AppCompat and you want to set the primary color for the screen. For this, you must theme the entire Activity:
<style name="MyTheme">
<style name="colorPrimary">#color/my_primary_color</style>
</style>
Themes use the same data structure as styles - even using the style tag - but they are, in fact, used in totally different circumstances! They don't operate on the same attributes - for example, you can define a textColor on a View, but there is no textColor attribute for a theme. Likewise, there exists colorPrimary in themes, but in styles they go unused. Thus:
Rule #8: DO NOT mix styles and themes.
Two common mistakes I've seen:
Applying a theme (as a style) to a `View`:
It just makes no sense because a `View` can't use any of the theme attributes anyways. Nothing happens.
Combining the themes/styles in your hierarchy via parenting. I've seen this as a result of people trying to maintain the illusion of hierarchy using dot notation:
Stupid! So, stupid! It does not make any sense and sometimes misfires in strange ways. Just don't do it!
As of Lollipop, you can apply themes to a View and all its children2. Even in that circumstance, you shouldn't mix up the two, though you could use them both in parallel:
<View
style="#style/MyView"
android:theme="#style/MyTheme" />
AppCompat has a simulacrum of View theming for the Toolbar, but that's all you'll get for a while until Lollipop is the minimum supported version of your app. In other words - you can have fun with this feature in a couple years. :P
Conclusion
The unifying element of these rules are to be careful and thoughtful when using styles. They can save you time, but only if you know when to use them.
Font: this article
When building my app, I started just using the Theme.Light.NoTitleBar.Fullscreen theme. I built all my layouts for the whole app like this, and got things to look how I want them. Some drawables used in the layouts have their size specifically set, and others are set to wrap_content.
I then decided to switch to the Holo light theme. When I do this, all the drawables used in layouts that are set to wrap_content end up larger. Almost as if they are pulling from a larger bucket. In fact, some look like they've been stretched.
I know the background is black in the older theme one, but that's not an issue (this is actually a layout file that is included in another layout). Obviously there's quite a difference in size between the two.
Here is just my guess based on what I read in this thread.
It can be because you use those images as background property of Button views. This is not safe because depending on default margin values - which are defined in the Theme - Buttons can stretch background images as they need to. If this is the case, then you need to use ImageButton views instead and use setImage*() method to assign images. There you can use scaleType property as it was mentioned by Carlos Robeles.
The only thing that comes to my mind, is that the different themes has different values for the defaultandroid:scaleType attribute of the image views.
Please, try specifying the attribute as some that is good for you, and see what happens using the 2 different themes. For example you can use android:scaleType="center", so your ImageViews would be something like
<ImageView
android:scaleType="center"
android:width="wrap_content"
android:height="wrap_content"
android:src="...
Yo can take a look at the different scale types in the ImageView reference:
http://developer.android.com/reference/android/widget/ImageView.html#attr_android:scaleType
It is not easy to understand what's the meaning of every type, so the best is to take a minute to play with them
My guess is that for some reason, the Holo theme is rendering your images in a lower resolution than Light. I mean that for instance you have your drawables in the drawable-xhdpi and Holo is treating them as drawable-hdpi. In fact, I don't have any evidence of that, but recently I've been messing around with resolutions and the difference seems very familiar to me.
If you don't have your drawables in the drawable-xxhdpi (the biggest resolution) folder, you could try putting them into a higher lever resolution folder, to see what happens.
From android's source code, see https://github.com/android/platform_frameworks_base/blob/master/core/res/res/values/styles.xml
The style which your button will be used in Holo.Light is
<style name="Widget.Holo.Light.Button" parent="Widget.Button">
<item name="android:background">#android:drawable/btn_default_holo_light</item>
<item name="android:textAppearance">?android:attr/textAppearanceMediumInverse</item>
<item name="android:textColor">#android:color/primary_text_holo_light</item>
<item name="android:minHeight">48dip</item>
<item name="android:minWidth">64dip</item>
</style>
See the last two lines. It has default minHeight and minWeight. That's why your button is stretched.
Solutions
1. Set minHeight and minWidth of your Button to 0.
2. Use a custom style like this.
<style name="MyHoloLightButtonStyle">
<item name="android:background">#android:drawable/btn_default_holo_light</item>
<item name="android:textAppearance">?android:attr/textAppearanceMediumInverse</item>
<item name="android:textColor">#android:color/primary_text_holo_light</item>
</style>
3. Use a ImageButton, and set your images by setImage*(not setBackround*) method.
Can anyone tell me how I can change my apps theme from the default ones made available? Holo and Holo.Light get a bit boring after a while.
The likes of Facebook, Google+, BBC Weather, Viber, Vine and Twitter all look very professional and have their own theme whereas the app I'm developing looks quite boring.
Is it possible to change the font of the text in my app? I know it's possible to change the colour and size of it.
Another thing which would be useful to know would be how to change the colour of the action bar that is used for my app. Currently it's black but I wouldn't mind changing it to a different colour than those used by the Android default themes (e.g. purple, green, blue, etc)
Maybe you can share some tips on what you think works well for Android design?
You can generate a custom theme at http://jgilfelt.github.io/android-actionbarstylegenerator/
If you only want to change a few font an colors etc take a closer look at this (source:http://developer.android.com/guide/topics/ui/themes.html)
If you like a theme, but want to tweak it, just add the theme as the parent of your custom theme. For example, you can modify the traditional light theme to use your own color like this:
<color name="custom_theme_color">#b0b0ff</color>
<style name="CustomTheme" parent="android:Theme.Light">
<item name="android:windowBackground">#color/custom_theme_color</item>
<item name="android:colorBackground">#color/custom_theme_color</item>
</style>
(Note that the color needs to supplied as a separate resource here because the android:windowBackground attribute only supports a reference to another resource; unlike android:colorBackground, it can not be given a color literal.)
Now use CustomTheme instead of Theme.Light inside the Android Manifest:
<activity android:theme="#style/CustomTheme">
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.