Android: Applying theme directly to CheckBox breaks 'android:onClick' - android

I've been working on this app for a while, and had zero issue with android:onClick's linking up with the relevant method in the activity.
...Then I started messing with themes and my CheckBox onClick's began breaking if I apply the theme directly to them with a 'android:theme="#style/CheckBoxTheme"', to the tune of this:
java.lang.IllegalStateException: Could not find a method onLinkCheckboxClicked(View) in the activity class android.view.ContextThemeWrapper for onClick handler on view class android.support.v7.widget.AppCompatCheckBox with id 'chx_sub_all'
If I DON'T use android:theme on the checkBoxes and just let the RF_AppTheme do it's thing, I can alter the checkbox with android:buttonTint just fine. onClicks work no problem. (The reason I'm splitting this into it's own specific theme is because I want to support a lower version, so I have a 'value/styles.xml' that just changes the background color, and a 'values-r21/styles.xml' that uses buttonTint which is version 21+ )
From what I can tell, the theme being used is changing the version of CheckBox, so that it tries to look at an activity that isn't my MainActivity, which doesn't exist.
My theme is literally a copy/paste of the theme generated with the project, with more things added to it:
<resources>
<style name="RF_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>
<item name="android:background">#color/colorBackground</item>
<item name="android:textSize">#dimen/text_size</item>
<item name="android:textColor">#color/colorTextNormal</item>
<item name="android:buttonTint">#color/colorPrimaryLight</item>
</style>
<style name="CheckBoxTheme" parent="RF_AppTheme">
<item name="android:buttonTint">#color/colorPrimaryLight</item>
<item name="android:gravity">center_vertical</item>
</style>
</resources>
This is the general idea of what my MainActivity looks like, without all the other code copy/pasted over.
public class MainActivity extends AppCompatActivity {
//onStart and the like above
public void onLinkCheckboxClicked(View view)
{
//doing checkbox things here, which never gets called
}
}
and this is one of my checkboxes
<CheckBox android:id="#+id/chx_sub_all"
android:theme="#style/CheckBoxTheme"
android:text="#string/check_all"
android:textColor="#color/colorTextNormal"
android:gravity="center_vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:onClick="onLinkCheckboxClicked"/>

Related

Setting a different theme

I want to use a few themes, for instance, Dark and Light.
I have written in the style.xml two different styles: DarkStyle and LightStyle. I have set part of the volatile properties by color.xml and part straight away.
<style name="BaseTheme.LightStyle">
<item name="clientBrand">#color/clientBrand</item>
<item name="desktopScreenBg">#E6E6E6</item>
</style>
<style name="BaseTheme.DarkStyle">
<item name="clientBrand">#color/clientBrand</item>
<item name="desktopScreenBg">#000000</item>
</style>
Which is the best practice to the choice theme
a. Build time?
b. Run time?
How I can to set to some other theme values from my theme.
<style name="OtherTheme">
<item name="android:textColor">dependsOnChosenTheme</item>
</style>
The final goal is:
<ViewGroup background = DarkOrLightColorBg/>
<TextView textColor = DarkOrLightColorBg/>
I figured out how to bind the desired theme in the build time
<style name="LightStyle">
<style name="DarkStyle">
//by requrements
<style name="DarkStyle.ActiveStyle">
Now, how I can do something like this?
<ViewGroup backgroun=ActiveStyle.colorBg/>
//Or
<style SomeTheme
<item name="android:textColor">#style/ActiveStile.colorText</item>
</style>
Here is an example how to create multi theme app. It is so easy, your activity has a context, inside context you could override method to inject selected theme by user.
Also if you don't need to runtime change, you could change theme at compile time, in AndroidManifest.xml.

Making android:windowBackground as #null by overriding the theme makes the view to repeat

I recently moved one of my activities(starting with a blank activity in Android Studio) to a full screen activity. Earlier, my activity looked like this.
I have few custom views inside my layout. To make my activity full screen, I just created a new full screen activity using the option in Android Studio and copied my code to the new activity. I noticed that the newly created full screen activity generated a theme overriding the application theme and then assigns this theme to the activity. The generated theme is as follows:
<style name="FullscreenTheme" parent="MyDefaultTheme">
<item name="android:actionBarStyle">#style/FullscreenActionBarStyle</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowBackground">#null</item>
<item name="metaButtonBarStyle">?android:attr/buttonBarStyle</item>
<item name="metaButtonBarButtonStyle">?android:attr/buttonBarButtonStyle</item>
</style>
<style name="FullscreenActionBarStyle" parent="Widget.AppCompat.ActionBar">
<item name="android:background">#color/black_overlay</item>
</style>
The problem I face is that the item
<item name="android:windowBackground">#null</item>
causes the activity view to be rendered like this:
If I comment that line in the new theme (or give it a color), everything seems to be working fine. I read few articles like this to understand this but I am still not clear what is happening in my case. Any explanations for this issue?
Also, I do not see any utility of
<style name="FullscreenActionBarStyle" parent="Widget.AppCompat.ActionBar">
<item name="android:background">#color/colorBackgroundLT</item>
</style>
Can anybody explain this as well?

Android TimePickerDialog styling guide/docs?

I'm trying to style a TimePickerDialog for sdk 21+ (Lollipop). So far I've figured out how to change the default colorscheme in XML:
<style name="TimePickerTheme" parent="#style/Theme.AppCompat.Light.Dialog">
<item name="colorPrimary">#ff2d6073</item> <!-- no effect -->
<item name="colorPrimaryDark">#ff2d6073</item> <!-- no effect -->
<item name="colorAccent">#ff2d6073</item>
<item name="android:textColor">#ffD0D102</item>
<item name="android:textColorPrimary">#ffD0D102</item>
</style>
This works but I'm looking for a guide or documentation for all the properties I can change.
AccentColor does the basic color scheme
TextColorPrimary does the text color
But what property, for example, do I need to change the big text in the 'header' of the dialog (where the current selected time is displayed)?
Is there some documentation that lists all the possible things you can change?
After digging through the AOSP theme and style xml files and a lot of googling I made some progress. I am now able to style most(!) things.
So this is a partial answer, not all the way there yet. But here's how far I got:
You can see that I'm now able to theme the header, the un(!)selected time part (minutes in this case), the circle, the numbers in that circle and the 'hand' (or selector). Oh, and the buttons are styled, too.
Let me explain how I got things working, first: the important thing is that you can't override things directly from you app's theme OR from a (alert)dialog theme/style. You have to go from one to the next, so to speak.
Example:
AndroidManifest.xml: Set custom theme for app and/or activity
<activity>
android:theme="#style/Theme.MyTheme"
</activity>
values-v21/styles.xml: (where your custom theme resides): set the timePickerDialogTheme
<style name="Theme.MyTheme" parent="#style/Theme.AppCompat.Light">
<item name="android:timePickerDialogTheme">#style/TimePickerDialogTheme</item>
</style>
Then below that, define the timePickerDialogTheme and set the timePickerStyle:
<style name="TimePickerDialogTheme" parent="#style/Theme.AppCompat.Light.Dialog">
<item name="colorAccent">#ff2d6073</item> <!-- colorAccent here seems to work just fine? -->
<item name="android:timePickerStyle">#style/TimePickerDialogStyle</item>
</style>
Now you can define most of the styling here..
<style name="TimePickerDialogStyle" parent="#android:style/Widget.Material.Light.TimePicker">
<item name="colorAccent">#ff2d6073</item> <!-- colorAccent here seems to work just fine? -->
<item name="android:timePickerMode">clock</item>
<item name="android:headerBackground">#ff2d6073</item>
<item name="android:headerTimeTextAppearance">#style/TextAppearance.TimePickerDialogStyle.TimeLabel</item> <!-- TimePicker Time *TextAppearance* -->
<item name="android:numbersTextColor">#ff000000</item>
<item name="android:numbersSelectorColor">#ff2d6073</item>
<item name="android:numbersBackgroundColor">#ffdddddd</item>
</style>
The important line in the above is:
<item name="android:headerTimeTextAppearance">#style/TextAppearance.TimePickerDialogStyle.TimeLabel</item>
Because if you want to style the text (well, time, actually) in the header you need to define the headerTimeTextAppearance:
<style name="TextAppearance.TimePickerDialogStyle.TimeLabel" parent="#android:style/TextAppearance.Material">
<item name="android:textSize">60sp</item> <!-- from -->
<item name="android:textColor">#ffD0D102</item>
</style>
Now, if you take a look at the Widget.Material.TimePicker in AOSP styles.xml (ctrl-f 'timepicker' until you find it) you'll notice a bunch of other properties that you should be able to modify:
headerTimeTextAppearance
headerAmPmTextAppearance
headerSelectedTextColor
headerBackground
numbersTextColor
numbersBackgroundColor
amPmTextColor
amPmBackgroundColor
amPmSelectedBackgroundColor
numbersSelectorColor
Most of these work (as long as you prepend 'android:' for each of them) BUT I could not get 'headerSelectedTextColor' to work. I got a compile error saying something like "could not match property bla bla". Also, if you look at my example above, I hardcoded the textSize for the 'headerTimeTextAppearance' property because the '#dimen/timepicker_ampm_label_size' value threw errors.
In short: most of the things are listed above and how to get them working. But not all is clear. So I'd still see that complete documentation/guide :)
Android TimePicker material style with custom colors below, you can see http://www.zoftino.com/android-timepicker-example for TimePicker usage and styles.
<style name="MyAppThemeFour" parent="Theme.AppCompat.Light">
<item name="android:timePickerDialogTheme">#style/MyTimePickerDialogStyle</item>
</style>
<style name="MyTimePickerDialogStyle" parent="#style/ThemeOverlay.AppCompat.Dialog.Alert">
<item name="showTitle">false</item>
<item name="colorControlActivated">#ffd600</item>
<item name="colorAccent">#b71c1c</item>
<item name="android:textColorPrimary">#43a047</item>
<item name="android:textColorSecondary">#f44336</item>
</style>
When using version 1.5.0 of the Material Design Library for Android, I've found that I can get most of the theming with using this particular style:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyTimePickerTheme" parent="ThemeOverlay.MaterialComponents.TimePicker">
<item name="android:textColor">#FF121212</item>
<item name="android:textColorPrimary">#FF121212</item>
<item name="android:textColorSecondary">#FFF9F9F9</item>
<item name="colorAccent">#FF121212</item>
<item name="colorControlNormal">#FF121212</item>
<item name="colorPrimary">#FF121212</item>
<item name="colorSurface">#FFF9F9F9</item>
</style>
</resources>
This will yield in a generic - non colored - Dialog which works for white theme. For dark theme, simply invert the colors.
I've also asked here to have dynamic theming supported for this component.
Example screenshot using the above style:

Overwrite default list view highlighted color in AppCompat theme

My application's main theme inherits from Theme.AppCompat, and I've created a selector that allows for the Ripple effect to take place when you press and focus a button on Lollipop.
However, when I go back to a 4.0 device, it defaults back to an ugly blue color when I focus a list view item. I've looked everywhere for the trait that defines this color hoping to override it without any luck - any idea how I can do this?
Add this to your theme:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
...
<item name="android:listViewStyle">#style/ListViewAppTheme</item>
<item name="android:listViewWhiteStyle">#style/ListViewAppTheme.White</item>
</style>
<style name="ListViewAppTheme" parent="Base.Widget.AppCompat.ListView">
<item name="android:listSelector">#drawable/abc_list_selector_dark</item>
<item name="android:divider">#drawable/ab_divider_light</item>
<item name="android:dividerHeight">1px</item>
</style>
<style name="ListViewAppTheme.White" parent="Base.Widget.AppCompat.ListView.White">
<item name="android:listSelector">#drawable/abc_list_selector_dark</item>
<item name="android:divider">#drawable/ab_divider_light</item>
<item name="android:dividerHeight">1px</item>
</style>
Change #drawable/abc_list_selector_dark to whatever selector you want to use. As an added bonus, I added how to change the listview's divider and its height.
Unfortunately doesn't seem to be working. The list views still seem to
be getting that disgusting default blue color from SOMEWHERE, although
I can't figure out where.
I used to feel like you, both on the disgusting and the angry somewhere part. However I managed to get rid of it.
If I remember well, the culprit should be android:listChoiceBackgroundIndicator. Try this:
<style name="MainTheme" parent="Theme.AppCompat">
<item name="android:listChoiceBackgroundIndicator">#drawable/my_selector</item>
<item name="listChoiceBackgroundIndicator">#drawable/my_selector</item>
</style>

Styling the popup menu in Android 5.0

I'm making my app ready for Android 5.0, I'm using the latest compatibility library, here is what my style looks like.
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#color/theme_accent</item>
<item name="colorAccent">#color/theme_accent_secondary</item>
</style>
<style name="AppThemeDark" parent="Theme.AppCompat">
<item name="colorPrimary">#color/theme_accent</item>
<item name="colorAccent">#color/theme_accent_secondary</item>
</style>
</resources>
(The ActionBar color is being set programmatically.)
Now, I want the overflow/popup menu to have the dark background like it had in the holo implementation, but I can't get it to work, here is what it looks like:
I have tried setting the popupMenuStyle but it didn't work.
How can I make the popup menu darker?
Stop using the ActionBar. If you want a ToolBar to be set up like an ActionBar, follow this guide on the android-developers blog.
It actually mentions your use case at Dark Action Bar and provides this code:
<android.support.v7.widget.Toolbar
android:layout_height=”wrap_content”
android:layout_width=”match_parent”
android:minHeight=”#dimen/triple_height_toolbar”
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
Not a full answer but what I found so far:
In past versions you needed to specify a drawable (Check https://github.com/StylingAndroid/StylingActionBar code and tutorials)
Apparently, now that is a color. To modify it you need to do specify the following theme:
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppTheme" parent="android:Theme.Material.Light.DarkActionBar">
<item name="android:actionBarPopupTheme">#style/popupNew</item>
</style>
<style name="popupNew" parent="android:ThemeOverlay.Material.Light">
<item name="android:colorBackground">#color/red</item>
</style>
</resources>
This works correctly if the theme applied to the app is just this.
If I add android:actionBarPopupTheme to my existing theme, it doesn't work. I am trying to figure out why.
Solved my problem by using this style:
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#color/theme_accent</item>
<item name="colorAccent">#color/theme_accent_secondary</item>
<item name="actionBarStyle">#style/AbStyle</item>
<item name="actionModeBackground">#color/actionmode_bg</item>
</style>
<style name="AbStyle" parent="Widget.AppCompat.Toolbar">
<item name="elevation">2dp</item>
<item name="displayOptions">homeAsUp|showTitle</item>
<!--showHome-->
</style>
<style name="AppThemeDark" parent="Theme.AppCompat">
<item name="colorAccent">#color/theme_accent_secondary</item>
<item name="actionBarStyle">#style/AbStyle</item>
</style>
I had to use Widget.AppCompat.Toolbar as the parent actionBarStyle
Add the property popupTheme to your toolbar:
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/color_primary"
app:theme="#style/Theme.AppCompat.Light"
app:popupTheme="#style/Theme.AppCompat" />
Or define a new style for your toolbar:
<style name="MyToolBarStyle" parent="Widget.AppCompat.Toolbar">
<item name="android:background">#color/green</item>
<item name="popupTheme">#style/Theme.AppCompat.Light</item>
<item name="theme">#style/Theme.AppCompat</item>
</style>
This question has already been answered for styling via XML, but I'm adding an explanation here of how to work out the solution to this and similar styling questions yourself.
First, this is the solution when using AppCompat. To your App's style.xml add actionBarPopupTheme to your theme:
<style name="Theme.MyTheme" parent="#style/Base.Theme.AppCompat.Light.DarkActionBar">
...other stuff here
<item name="actionBarPopupTheme">#style/Theme.MyTheme.ActionBarPopupTheme</item>
</style>
<style name="Theme.MyTheme.ActionBarPopupTheme" parent="#style/ThemeOverlay.AppCompat.Light">
<item name="android:textColor">#android:color/white</item>
<item name="android:background">#android:color/black</item>
</style>
Here's the steps I took to arrive at this solution (it takes a bit of detective work as the Android documentation is poor):
Open your App's style.xml in Android Studio
On the line where you App's theme is defined, put your screen cursor in the parent theme (e.g. click in #style/Base.Theme.AppCompat.Light.DarkActionBar) then press F4. This should take you to the source code for the style in the appcompat library.
Within this style I saw this line:
< item name="actionBarPopupTheme">#style/ThemeOverlay.AppCompat.Light< /item>
This looked like a possible place to change the theme of the popup. I searched for "actionBarPopupTheme" in the poor
Android developers documentation and found "Reference to a theme that should be used to
inflate popups shown by widgets in the action bar". So this was worth playing with.
I copied the appcompat line containing "actionBarPopupTheme" to my style.xml then in this line replaced the item's theme reference (the bit in bold above) with Theme.MyTheme.ActionBarPopupTheme.
In my style.xml I created my new style named Theme.MyTheme.ActionBarPopupTheme. I used the same parent that was used in the style I copied from the appcompat source (the bit in bold above).
To ensure my new popup style was working, I changed the parent style to ThemeOverlay.AppCompat.Dark then ran and tested the code on a device. The popup style changed, so now I knew my overriding of actionBarPopupTheme was the correct thing to do. Then I changed back to ThemeOverlay.AppCompat.Light.
The next challenge is to work out what item names to override in Theme.MyTheme.ActionBarPopupTheme. I changed the text and background colours. To find the correct item names that change the style of something can be tricky in some cases. One way to find less obvious style item names is to look through the style definitions in the appcompat xml file (the one you opened when pressing F4 in the 2nd step above), continually descending into parent styles (F4 again!) until you find something that may do what you want. Google searches will help here too.

Categories

Resources