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>
Related
Is it possible to specify colorPrimary and colorAccent for individual style elments rather than in theme tag
<style name="MyCustomTabLayout" parent="android:Widget">
<item name="colorPrimaryDark">#color/gray900</item>
<item name="colorAccent">#color/gray50</item>
<item name="tabBackground">?attr/colorPrimaryDark</item>
<item name="tabSelectedTextColor">?android:colorAccent</item>
</style>
<style name="MyCustomTabLayout2" parent="android:Widget">
<item name="colorPrimaryDark">#color/gray50</item>
<item name="colorAccent">#color/gray900</item>
<item name="tabBackground">?attr/colorPrimaryDark</item>
<item name="tabSelectedTextColor">?android:colorAccent</item>
</style>
When I try doing this the default theme is applied. Is there a way/better way to do this?
Widgets look up their accent colors etc on the context theme. You can define different themes to hold your styles, and apply them to different layouts using android:theme attribute, if you use the latest appcompat suport library. See https://chris.banes.me/2014/11/12/theme-vs-style/
Citing an example there:
res/values/themes.xml
<style name="RedThemeOverlay" parent="android:ThemeOverlay.Material">
<item name="android:colorEdgeEffect">#FF0000</item>
</style>
res/layout/fragment_list.xml
<ListView
...
android:theme="RedThemeOverlay" />
I'd like to have two themes in my app: one with normal font size and one with smaller font size. I need to dynamically change themes in the activity's onCreate or onStart.
I've defined two themes (file themes.xml):
<style name="AppBaseTheme" parent="android:Theme.Light">
</style>
<!-- Default theme with normal font size. This one is set for the whole app in the manifest -->
<style name="NormalTheme" parent="AppBaseTheme">
<item name="android:textAppearance">#style/NormalTextSize</item>
<item name="android:textAppearanceLarge">#style/NormalTextSize.Large</item>
<item name="android:textAppearanceMedium">#style/NormalTextSize.Medium</item>
<item name="android:textAppearanceSmall">#style/NormalTextSize.Small</item>
<item name="android:editTextStyle">#style/EditText_NormalTextSize</item>
</style>
<!-- Small font size -->
<style name="SmallFontTheme" parent="NormalTheme">
<item name="android:textAppearance">#style/SmallTextSize</item>
<item name="android:textAppearanceLarge">#style/SmallTextSize.Large</item>
<item name="android:textAppearanceMedium">#style/SmallTextSize.Medium</item>
<item name="android:textAppearanceSmall">#style/SmallTextSize.Small</item>
<item name="android:editTextStyle">#style/EditText_SmallTextSize</item>
</style>
And in the file styles.xml I've defined style sets for each theme:
<!-- Normal font -->
<style name="NormalTextSize" parent="#android:style/TextAppearance">
<item name="android:textSize">16sp</item>
</style>
<style name="NormalTextSize.Large" >
<item name="android:textSize">22sp</item>
</style>
<style name="NormalTextSize.Medium" >
<item name="android:textSize">18sp</item>
</style>
<style name="NormalTextSize.Small" >
<item name="android:textSize">14sp</item>
</style>
<style name="EditText_NormalTextSize" parent="#android:style/Widget.EditText">
<item name="android:textSize">16sp</item>
</style>
<!-- Small font -->
<style name="SmallTextSize" parent="#android:style/TextAppearance">
<item name="android:textSize">14sp</item>
</style>
<style name="SmallTextSize.Large" >
<item name="android:textSize">20sp</item>
</style>
<style name="SmallTextSize.Medium" >
<item name="android:textSize">16sp</item>
</style>
<style name="SmallTextSize.Small" >
<item name="android:textSize">12sp</item>
</style>
<style name="EditText_SmallTextSize" parent="#android:style/Widget.EditText">
<item name="android:textSize">14sp</item>
</style>
To test the theme change I've created an activity and I've added two TextViews (one with textAppearanceLarge and one with textAppearanceSmall). I've also added an EditText and a list view. I haven't touched any style attribute on these views, I've kept them as they are when dropped in the layout editor. My goal is to change the theme for the whole app without having to define style or appearance for each widget.
I've also added some buttons to trigger the theme change: the new theme resource id is stored in preferences, then the activity is self-finished and a new Intent to the same test activity is launched. The activity reads the current theme setting in onCreate or onStart and calls setTheme. This theme setting change works, but only the ListView is resizing the text: the TextViews and the EditText don't resize.
So my question is what on earth have I done wrong. I've followed 3-4 tutorials and my styles are consistent with what it is supposed to work.
Notice I've only overrided text appearances in the themes because I thought that almost every text-based widget would resize based on the appearance alone (when dropped from the layout editor, every widget has an appearance). I've readed somewhere that it doesn't work that way (if so, good job guys at Google) and that you need to define text size for every kind of widget inside the themes. Well in the example above I've overrided editTextStyle and didn't work. I have also tried buttons and text views with identical result. But what puzzles me is that the ListView, which is the most complex widget on screen, is resizing correctly without defining an style for it, while the most simple widgets are not, even when defining styles for those particular kind of widgets!
The themes were ok.
The problem was the activity. You need to call setTheme before setContentView.
Kudos to #mozarty for his answer
I'm trying to apply some styles to my app. I've created a custom theme for the ActionBar using this actionbarstylegenerator.
But I want to change also in my app, the stock blue Holo color, to a red one, at least on buttons.
So, I have the custom theme for the ActionBar (Compat), and for the other side, a custom theme to change the Holo color.
In my app, I have defined the custom theme for the Actionbar, and I want to set the custom Holo theme inside the Actionbar's theme, but I don't know how to call, or where can I find the item name's whose define the variable you want to modify.
This is, I need to set this:
<style name="ColorTheme" parent="android:Theme.Black">
<item name="android:checkboxStyle">#style/CheckBoxColorTheme</item>
<item name="android:buttonStyle">#style/ButtonColorTheme</item>
<item name="android:imageButtonStyle">#style/ImageButtonColorTheme</item>
</style>
Inside of this:
<style name="Theme.CustomActionBarTheme" parent="#style/Theme.AppCompat">
<item name="actionBarItemBackground">#drawable/ab_selectable_background</item>
<item name="popupMenuStyle">#style/PopupMenu</item>
<item name="dropDownListViewStyle">#style/DropDownListView</item>
<item name="actionBarTabStyle">#style/ActionBarTabStyle</item>
<item name="actionDropDownStyle">#style/DropDownNav</item>
<item name="actionBarStyle">#style/ActionBar.Transparent</item>
<item name="actionModeBackground">#drawable/cab_background_top_customactionbartheme</item>
<item name="actionModeSplitBackground">#drawable/cab_background_bottom_customactionbartheme</item>
<item name="actionModeCloseButtonStyle">#style/ActionButton.CloseMode</item>
</style>
Maybe you need to do this?
<style name="ColorTheme" parent="Theme.CustomActionBarTheme">
<item name="android:checkboxStyle">#style/CheckBoxColorTheme</item>
<item name="android:buttonStyle">#style/ButtonColorTheme</item>
<item name="android:imageButtonStyle">#style/ImageButtonColorTheme</item>
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"
[...] />
I have a style that includes textColor, textSize, textStyle and typeface. When applied directly to an EditText widget, the color of the text is as specified (as well as the other attributes), but when applied as a theme to the activity or the entire application, the size is fine but the color is not applied. What I am missing?
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="fap" parent="android:Theme.Holo">
<item name="android:textSize">24sp</item>
<item name="android:textColor">#FF0000</item>
<item name="android:textStyle">normal</item>
<item name="android:typeface">normal</item>
</style>
</resources>
This is quite simple : you are not overriding android default style, your just creating a new one which extends android:Widget.EditText. Thus, the style is not applied.
To correct this, into your theme definition, just add :
<item name="android:editTextStyle">#style/fap</item>
Now, each time Android instanciate an EditText, when it load default style values, it will find your fap style.
Edit:
searching through android's source code is very usefull. Check https://android.googlesource.com/platform/frameworks/base/+/master/core/res/res/values/attrs.xml
https://android.googlesource.com/platform/frameworks/base/+/master/core/res/res/values/themes.xml
https://android.googlesource.com/platform/frameworks/base/+/master/core/res/res/values/styles.xml
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/widget/EditText.java
for example.
EditText widget just can't get these parameters from an activity theme. It gets its default style from the android:editTextStyle parameter of the activity theme. So you have to create your own style:
<style name="MyEditText" parent="android:Widget.EditText">
<item name="android:textSize">24sp</item>
<item name="android:textColor">#FF0000</item>
<item name="android:textStyle">normal</item>
<item name="android:typeface">normal</item>
</style>
And then set it as EditText style in the activity theme:
<style name="fap" parent="android:Theme.Holo">
<item name="android:editTextStyle">#style/MyEditText</item>
</style>
Hope this will work because I haven't tried this code.