Style selector? - android

I have two holo based ABS styles, Purple and Lime, users are able to set the theme from settings.
In my layout I have a TextView with a custom textAppearance, I want to change that textAppearance based on the active style.
(if the purple theme is activated the text must be white and if the lime theme is activated the text must be lime)
Is there a way to do that from the XML?
Edit
I'm sorry if the title is misleading.

(if the purple theme is activated the text must be white and if the
lime theme is activated the text must be lime)
Try that:
<style name="PurpleTheme" parent="...">
<!-- define the style for the text appearance here. Following is an example -->
<item name="android:textAppearance">#style/MyWhiteText</item>
</style>
<style name="LimeTheme" parent="...">
<!-- define the style for the text appearance here. Following is an example -->
<item name="android:textAppearance">#style/MyLimeText</item>
</style>
<style name="MyWhiteText" parent="#android:style/TextAppearance">
<item name="android:textColor">#color/white</item>
</style>
<style name="MyWhiteText" parent="#android:style/TextAppearance">
<item name="android:textColor">#color/lime</item>
</style>
Or if you don't want to set the color to all TextViews then do this:
Declare an attribute:
<attr name="myTextViewColor" format="reference" />
Use it like this in your theme:
<style name="PurpleTheme" parent="...">
<item name="myTextViewColor">#color/white</item>
</style>
<style name="LimeTheme" parent="...">
<item name="myTextViewColor">#color/lime</item>
</style>
Now you can set the color of the specific TextView like this:
<TextView
android:textColor="?attr/myTextViewColor"
[...] />

Related

Xamarin Android - Change colors for TimePicker keyboard view

I was able to change the color setting for the clock view
(That was helpful https://www.tutorialsbuzz.com/2019/09/android-timepicker-dialog-styling.html)
But I wasn't so successful at the second view (press the keyboard icon at the bottom left of the first image). How to change the color of SubTitle, InputField and description (center of the image that looks pure black)? Has anyone an idea?
Is there a documentation that I overlook? Would be great to have a list with all keys like "android:numbersTextColor" etc. for the color pallet of the second view.
I appreciate your time and effort. Thanks :-)
Edit
"Leon Lu - MSFT" thanks for your answer. That made it possible to style the view under "Keyboard". Is it possible to set different colors for the text above and below the input field, the "AM"/"PM" text and "cancel"/"ok"?
Unfortunately the clock view changed into this after applying the provided style.
Complete Android Style
<style name="MainTheme" parent="MainTheme.Base">
</style>
<!-- Base theme applied no matter what API -->
<style name="MainTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<!--If you are using revision 22.1 please use just windowNoTitle. Without android:-->
<item name="windowNoTitle">true</item>
<!--We will be using the toolbar so no need to show ActionBar-->
<item name="windowActionBar">false</item>
<!-- Set theme colors from https://aka.ms/material-colors -->
<!-- colorPrimary is used for the default action bar background -->
<item name="colorPrimary">#2196F3</item>
<!-- colorPrimaryDark is used for the status bar -->
<item name="colorPrimaryDark">#1976D2</item>
<!-- colorAccent is used as the default value for colorControlActivated
which is used to tint widgets -->
<item name="colorAccent">#f59b00</item>
<!-- You can also set colorControlNormal, colorControlActivated
colorControlHighlight and colorSwitchThumbNormal. -->
<item name="windowActionModeOverlay">true</item>
<item name="android:datePickerDialogTheme">#style/AppCompatDialogStyle</item>
<item name="android:timePickerDialogTheme">#style/TimePickerLightTheme</item>
<item name="android:timePickerStyle">#style/TimePickerLightStyle</item>
<item name="android:textAllCaps">false</item>
</style>
<style name="AppCompatDialogStyle" parent="Theme.AppCompat.Light.Dialog">
<item name="colorAccent">#f59b00</item>
</style>
<style name="TimePickerLightTheme" parent="Theme.AppCompat.Light.Dialog">
<item name="android:background">#4b4b4b</item>
<item name="android:colorAccent">#2c2f30</item>
<item name="android:textColor">#f59b00</item>
<item name="android:textColorPrimary">#ffffff</item>
</style>
<style name="TimePickerLightStyle" parent="android:Widget.Material.Light.TimePicker">
<item name="android:headerBackground">#2c2f30</item>
<item name="android:numbersTextColor">#ffffff</item>
<item name="android:numbersInnerTextColor">#ffffff</item>
<item name="android:numbersSelectorColor">#f59b00</item>
<item name="android:numbersBackgroundColor">#4b4b4b</item>
<item name="android:background">#1f1f1f</item>
<item name="android:textColorPrimary">#a1a1a1</item>
</style>
Is there a list with keys for all elements that I'm overlooking? Would be great to have a list where it says something like "Key X is for color of view element Y".
Do you want to change the color of SubTitle, InputField and description like following screenshot?
Create the Theme.picker style.
<style name="Theme.picker" parent="Theme.AppCompat.Light.Dialog">
//background color
<item name="android:background">#FFC107</item>
//Title background color
<item name="colorAccent">#FF0000</item>
//text color
<item name="android:textColor">#android:color/white</item>
//edittext color
<item name="android:textColorPrimary">#android:color/holo_green_light</item>
</style>
Them use it in the Timepicker.
<TimePicker
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/Theme.picker"/>
If you used xamarin forms.You should add an item in <style name="MainTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:timePickerDialogTheme">#style/Theme.picker</item>
=====update======
Is it possible to set different colors for the text above and below the input field, the "AM"/"PM" text and "cancel"/"ok"?
If you want to set it, just change the color in the <item name="android:textColor">#android:color/red</item> tab. The textcolor of firstview and second view will be changed, it set both of them at the same time. If you want to set the diferent items for differen view, you should make a custom TimePicker

Android Material Chip Theme overriding

I want to customize a Material chip.
I would think this is how to do it:
<style name="AppTheme" parent="Theme.MaterialComponents.NoActionBar">
.... lots more theme stuff here
<item name="chipStyle">#style/MaterialChips</item>
<item name="chipGroupStyle">#style/MaterialChips</item>
<item name="chipStandaloneStyle">#style/MaterialChips</item>
</style>
<style name="MaterialChips" parent="Widget.MaterialComponents.Chip.Choice">
<item name="chipBackgroundColor">#color/chips</item>
</style>
None of the tags like chipStyle affect the chips. But if I set app:chipBackgroundColor="#color/chips" in xml it works.
It also works fine like this for other things like say <item name="materialAlertDialogTheme">#style/AlertDialogTheme</item>.
The material documentation (if you can call it that) is really not helping.
Your app theme is correct.
The default style used by Chip component is defined in the app theme by the chipStyle attribute.
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
<!-- Default style for chip component -->
<item name="chipStyle">#style/Widget.MaterialComponents.Chip.Action</item>
</style>
You can customize this style using for example:
<style name="AppTheme" parent="Theme.MaterialComponents.*">
<!-- Default value for chipStyle -->
<item name="chipStyle">#style/MaterialChips</item>
</style>
<style name="MaterialChips" parent="#style/Widget.MaterialComponents.Chip.Choice">
<!-- ... -->
<item name="chipBackgroundColor">#color/chips</item>
</style>
If you specify the style attribute in your layout, this style overrides the default value.
<com.google.android.material.chip.Chip
style="#style/Widget.MaterialComponents.Chip.Entry"
.../>
In this case the Chip uses the Widget.MaterialComponents.Chip.Entry style.
if you define chip style in layout xml, chip override your theme.
It may work if you clear chip style in layout xml.

Theme/Style all checkboxes

I am trying to understand how to change the look of all checkboxes within my application for a certain theme.
I would like to change the checkbox check color and the checkbox border color.
If I create this style:
<style name="MyCheckBox" parent="Widget.AppCompat.CompoundButton.CheckBox">
<item name="colorControlNormal">#8AFFFFFF</item>
<item name="colorControlActivated">#android:color/white</item>
</style>
And apply it as a theme on my checkbox it works great.
<CheckBox
android:id="#+id/status_favorite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="#style/MyCheckBox"/>
However I don't really want to apply that theme to every checkbox, I would like to set the theme for all checkboxes.
I tried to set the checkboxStyle in my theme however this doesn't work.
<style name="MyTheme" parent="Theme.AppCompat">
...
<item name="checkboxStyle">#style/MyCheckBoxStyle</item>
...
</style>
<style name="MyCheckBoxStyle" parent="Base.Widget.AppCompat.CompoundButton.CheckBox">
<item name="colorControlNormal">#8AFFFFFF</item>
<item name="colorControlActivated">#android:color/white</item>
</style>
Is there a way to set a default theme for all checkboxes?
Unfortunately, colorControlNormal and colorControlActivated are theme attributes, not style attributes, so they only work if they're defined in the view's theme. There is no way that I know of to set a "default theme" for all views of a certain type; attributes like checkboxStyle can only set a default style for all checkboxes. Additionally, you can't "trick" the system by writing something like:
<style name="MyTheme" parent="Theme.AppCompat">
...
<item name="checkboxStyle">#style/MyCheckBoxStyle</item>
...
</style>
<style name="MyCheckBoxStyle" parent="Base.Widget.AppCompat.CompoundButton.CheckBox">
<item name="android:theme">#style/MyCheckboxTheme</item>
</style>
<style name="MyCheckboxTheme">
<item name="colorControlNormal">#8AFFFFFF</item>
<item name="colorControlActivated">#android:color/white</item>
</style>
Your choices are:
Modify colorControlNormal and colorControlActivated in your app's theme
Modify colorControlNormal and colorControlActivated in your activity's theme
Manually set the android:theme attribute to every checkbox you want to change (or to the parent viewgroup holding these checkboxes)
Edit: potential workaround
Depending on your exact requirements, you might be able to get away with this:
<style name="MyTheme" parent="Theme.AppCompat">
<item name="checkboxStyle">#style/MyCheckboxStyle</item>
</style>
<style name="MyCheckboxStyle" parent="Widget.AppCompat.CompoundButton.CheckBox">
<item name="buttonTint">#8AFFFFFF</item>
</style>
This will change the color of every checkbox in your app without requiring the use of theme attributes. You can even use a color selector resource for buttonTint if you want different colors for checked/unchecked:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#android:color/white" android:state_checked="true"/>
<item android:color="#8AFFFFFF"/>
</selector>

Android AppCompat AlertDialog styling with theme

I wish to be able to set a theme to set the message text size in an AppCompat AlertDialog. The theme needs to have parent="#style/Theme.AppCompat.Dialog". I have spent hours searching and trying all the suggestions, but none of them seem to work with that base theme.
If the parent is changed to the Holo theme, then I can alter the message text size using textAppearanceMedium, but the rest of the dialog looks really ugly :S
Currently my theme is (all this is currently hooked up and working):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyDialogTheme" parent="#style/Theme.AppCompat.Dialog">
<!-- Used for the buttons -->
<item name="colorAccent">#color/colorPrimary</item>
<!-- Button text size -->
<item name="android:textSize">#dimen/ui_text_size</item>
<!-- Content text color -->
<item name="android:textColorPrimary">#color/ui_text_color</item>
<!-- Title style -->
<item name="android:windowTitleStyle">#style/MyDialogTitleStyle</item>
<!-- Button style (except size) -->
<item name="android:textAppearanceButton">#style/MyDialogButtonTextAppearance</item>
<!-- Dialog background -->
<item name="android:windowBackground">#color/ui_background</item>
</style>
<style name="MyDialogTitleStyle" parent="#style/RtlOverlay.DialogWindowTitle.AppCompat">
<item name="android:textAppearance">#style/MyDialogTitleTextAppearance</item>
<item name="android:textSize">#dimen/ui_large_text_size</item>
</style>
<style name="MyDialogTitleTextAppearance">
<item name="android:textSize">#dimen/ui_large_text_size</item>
<item name="android:textAllCaps">true</item>
<item name="android:textColor">#color/ui_title_color</item>
</style>
<style name="MyDialogButtonTextAppearance">
<item name="android:fontFamily">sans-serif-light</item>
<item name="android:textAllCaps">true</item>
</style>
</resources>
Seems like there is no way to this via a theme attribute. Let's look at the source code of appcompat-v7 library. Following the TextView that reflects the message of the AlertDialog:
<android.support.v7.widget.AlertDialogLayout ... >
<!-- ... -->
<TextView
android:id="#android:id/message"
style="#style/TextAppearance.AppCompat.Subhead"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="?attr/dialogPreferredPadding"
android:paddingRight="?attr/dialogPreferredPadding"/>
<!-- ... -->
</android.support.v7.widget.AlertDialogLayout>
As you can see the TextView uses the TextAppearance.AppCompat.Subhead as the style. Following its definition:
<style name="TextAppearance.AppCompat.Subhead" parent="Base.TextAppearance.AppCompat.Subhead"/>
<style name="Base.TextAppearance.AppCompat.Subhead">
<item name="android:textSize">#dimen/abc_text_size_subhead_material</item>
<item name="android:textColor">?android:textColorPrimary</item>
</style>
The textSize is static and isn't resolved via an attribute like the textColor (which uses the textColorPrimary). Thus there's no option for us to set the textSize. The only way to do it would be to override the TextAppearance.AppCompat.Subhead style by adding it to your own styles.xml file and set the textSize to whatever value you need. But be aware there may be side effects since this style can be used in other places as well.
tl;dr
Options:
Define TextAppearance.AppCompat.Subhead in your styles.xml file and override the textSize attribute.
Do it programatically (find TextView by id and #setTextSize)
Use your own layout in the dialog - the source code of appcompat-v7 may be a good starting point.

Override Android background in custom style for one theme but not another

I'm using two themes for my Android application, AppTheme and AppThemeDark. I've set up a custom button style for each in the theme definitions:
<!-- Theme definitions -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
...
<item name="android:buttonStyle">#style/ButtonStyle</item>
...
</style>
<style name="AppThemeDark" parent="Theme.AppCompat.DayNight.NoActionBar">
...
<item name="android:buttonStyle">#style/ButtonStyleDark</item>
...
</style>
<!-- Button styles -->
<style name="ButtonStyle" parent="#style/Widget.AppCompat.Button">
<item name="android:ellipsize">end</item>
<item name="android:maxLines">2</item>
</style>
<style name="ButtonStyleDark" parent="ButtonStyle">
<item name="android:background">#drawable/gray_button_bg</item>
</style>
Note that my AppTheme button, ButtonStyle, doesn't override the background of Widget.AppCompat.Button, but AppThemeDark's button style inherits ButtonStyle and it changes the background.
Now, I would like to extend that buttonStyle with a new custom style for special buttons, e.g. PrimaryButton. In the AppTheme case, I do not want to change the background of the button. In the AppThemeDark case, i do want to change the background of the button.
I would like to define PrimaryButton and have it either inherit the background (in the case of AppTheme) or use a new background (AppThemeDark). Something like this:
<style name="PrimaryButton">
<item name="android:background">?attr/drawablePrimaryButtonBackground</item>
</style>
But as far as I can tell, there's no way to define an attribute in AppThemeDark as a new drawable and AppTheme as "inherit from parent". Setting to transparent obviously makes the button background in AppTheme transparent.
Is my only option to figure out what drawable is being used for a background in Widget.AppCompat.Button and define it locally?
To answer my own question...
You can dig up the private Android resource and use a local copy to retain the background. That locks you into one specific Android version of the drawable though (unless you copy multiple versions over).
You can set whole styles as attributes if the styles between your two themes are different enough to warrant it:
attrs.xml:
<attr name="stylePrimaryButton" format="reference" />
styles.xml:
<!-- Theme definitions -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
...
<item name="stylePrimaryButton">#style/PrimaryButton</item>
...
</style>
<style name="AppThemeDark" parent="Theme.AppCompat.DayNight.NoActionBar">
...
<item name="stylePrimaryButton">#style/PrimaryButtonDark</item>
...
</style>
<!-- Primary button styles -->
<style name="PrimaryButton">
<!-- no need to override anything -->
</style>
<style name="PrimaryButtonDark">
<item name="android:background">#drawable/dark_background</item>
</style>
layout.xml:
<Button style="?attr/stylePrimaryButton"
...

Categories

Resources