I have seen that some Style attributes require android prefix and some don't need it. What is the reason. like
<style name="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="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
Why we haven't use android:windowActionBar and android:windowNoTitle
Based on SDK version Android styles are grouped in different namespaces. In order to override a Theme you have to follow it's namespace.
That's the reason you don't need the android: prefix when extending an AppCompat Theme, but if you wanted something else, let's say Theme.Holo - you'd have 2 different styles for the them - one for pre-Lollipop devices, and one for -21, the latter having the android: prefix before each style attribute.
It depends on which Themes you're using and which context it is. These attributes are defined by different sources.
If the attribute name is prefixed with android:, it's a framework attribute and can only be used for the Android versions having it defined.
If the attribute is not prefixed at all, the attributes are defined by your own application. This includes all attribute definitions you pulled in with libraries.
In your example you're defining a theme for AppCompat which is part of the support library and thus of your application. The framework widgets won't recognize these colors directly.
Related
I have a com.google.android.material.button.MaterialButton component in one of my layout file and I get this error when I am using the latest version of the Material Components library (com.google.android.material:material:1.0.0-alpha3):
java.lang.IllegalArgumentException: This component requires that you specify a valid android:textAppearance attribute.
It wasn't present in 1.0.0-alpha1. Is this a bug in the library or should I just specify a textAppearance attribute from now?
Does your theme extend from Theme.MaterialComponents? More info about how to ensure all the components will work correctly can be found at https://material.io/develop/android/docs/getting-started/
If you are using any of the MaterialComponent, then your theme must extend from the following theme - Theme.MaterialComponents.Light.DarkActionBar
<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
If you want to keep using your old styles but only want to extend from 'Theme.MaterialComponents' then you can use 'Bridge'.
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar.Bridge">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorAccent</item>
<item name="colorAccent">#color/colorPrimaryDark</item>
</style>
if your theme does not extend MaterialComponents theme, and you want to keep the AppCompat theme, use a bridge theme, that would allow you to use material components keeping the AppCompat theme.
change your existing theme from:
<style name="AppTheme" parent="Theme.AppCompat.Light">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
to this:
<style name="AppTheme" parent="Theme.MaterialComponents.Light.Bridge">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
Does my theme extend from Theme.MaterialComponents? Oh yes indeed, and has been since I started using any of the new Material UI stuff.
If all these answers here are as unhelpful to you as they were to me, get ready: The This component requires that you specify a valid android:textAppearance attribute error can be related to an external library specifying android:theme with the same name as the theme you are using, and Android randomly deciding which one to use depending on your build.gradle. In my case the culprit was inside Mobile FFmpeg.
I started encountering this error after working for a week while the build variant was set to a different product flavor and then switching back the original one. What changed meanwhile? After thorough investigation I found the build broke after I split implementation 'com.arthenica:mobile-ffmpeg-min:4.2.2.LTS' in two, for each product flavor where I actually use it like this:
videoImplementation 'com.arthenica:mobile-ffmpeg-min:4.2.2.LTS'
mainImplementation 'com.arthenica:mobile-ffmpeg-min:4.2.2.LTS'
This was enough to trigger This component requires that you specify a valid android:textAppearance attribute for flavor main, while working fine for flavor video. Every main build crashed because my app's theme is named AppTheme and the Mobile FFmpeg manifest also specifies android:theme="#style/AppTheme" (which affects all versions up to 4.2.2). So I renamed my theme, but that resulted in a build error very similar to the one here:
https://github.com/tanersener/mobile-ffmpeg/issues/206
Attribute application#theme value=(#style/ScryptedTheme) from AndroidManifest.xml:37:9-45
is also present at [com.arthenica:mobile-ffmpeg-https:4.2.LTS] AndroidManifest.xml:17:9-40 value=(#style/AppTheme).
Suggestion: add 'tools:replace="android:theme"' to <application> element at AndroidManifest.xml:31:5-95:19 to override.
After adding said tools:replace="android:theme", everything worked again, and the original MaterialComponents error was gone.
But why is it OK for one flavor and not OK for the other? Absolutely no idea. Credit goes to Google's tendency to add the craziest bugs to "stable" releases. At least it's possible to solve very easily with some refactoring.
TL;DR
THIS is the issue: https://github.com/tanersener/mobile-ffmpeg/issues/206
Together with the fact that when two merged manifest specify different themes with the same name, Android will choose one randomly depending on the content of your build.gradle.
Solution: Add a tools:replace="android:theme" to your manifest's <application> tag and change the name of your theme.
Check if your AppTheme inherits from MaterialComponents as specified here.
<style name="Theme.MyApp" parent="Theme.MaterialComponents.Light">
<!-- ... -->
</style>
Remember to check all variants of styles.xml file. This was actually the issue I had.
I had the same problem, I changed my activity theme but it didnt resolved the issue. The i changed my main app theme from AppCompact to Theme.MaterialComponents
<application
android:allowBackup="true"
android:fullBackupContent="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme2">
<activity
android:name=".MainActivity"
android:label="#string/app_name"/>
</application>
Got stucked in this error even if my theme extends Theme.MaterialComponents. I was creating Chips like this :Chip chip = new Chip(getActivity().getBasecontext(), null, R.attr.CustomChipChoice);.
The solution is to change it to Chip chip = new Chip(getActivity(), null, R.attr.CustomChipChoice);.
Hope it helps.
I have included this dependence first
implementation 'com.google.android.material:material:1.2.0-alpha01'
Than I have set my project style as bellow
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
Extending Correctly? => Verify your styles!
In my case, I made a dumb auto-complete mistake:
<item name="textInputStyle">#style/Widget.MaterialComponents.Button.OutlinedButton</item>
What I really meant was TextInputLayout.OutlinedBox instead of Button.OutlinedButton:
<item name="textInputStyle">#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox</item>
Unfortunately this typo gives the same misleading error (despite extending the theme correctly):
Caused by: java.lang.IllegalArgumentException: This component requires
that you specify a valid TextAppearance attribute. Update your app
theme to inherit from Theme.MaterialComponents (or a descendant).
...sharing because it took me a long time to spot the error!
If you tried other answers on how to properly set parent theme for your app's theme, and you still get ...requires a value for to be set in your app theme., you may check if you have more than one place, where your app's theme is defined, as you may have separate themes.xml files for specific configuration, API versions etc.
For example:
res/values/themes.xml - default one
res/values-v23/themes.xml - for devices with API >= 23
<style name="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="colorWindowBackground">#color/Gray</item>
</style>
I wanted to add the property colorWindowBackground like so. Can I not just use any name I like? it seems like Android studio does not appreciate my behavior.
I'm guessing then that colorPrimary from item name is defined somewhere already. and that name can only be set to certain already existing properties.
how does the compiler know which properties are allowed? Is it somehow based on the parent the style is inherited from?
For using custom attributes in the views of layouts, you can use "declare-stylable" for custom names. Please follow below referred site :
https://guides.codepath.com/android/Defining-Custom-Views
#james Joshua, colorPrimary, colorAccent, and colorPrimaryDark are defined or in other words inherited from parent style Theme.AppCompat.Light.DarkActionBar.
I get this as one of my colors generated by the Material Design Color Platte.
But in this image:
I don't see colorPrimaryLight anywhere. What is it used for and how do I declare it? Do declare it like this in my style?:
<item name="colorPrimaryLight">#color/colorPrimaryLight</item>
Or do I declare it in a different way? And what is it used for?
By default, the statusBarColor is set to colorPrimaryDark. If you want to use colorPrimaryLight for the status bar you need to set android:statusBarColor to android:colorPrimaryLight.
https://developer.android.com/training/material/theme.html
in your resources file put:
<color name="colorPrimaryLight">#D1C4E9</color>
in your styles file put:
<item name="colorPrimaryLight">#color/colorPrimaryLight</item>
TL;DR: colorPrimaryLight is one of several colors identified as part of the Material palette that is not actually mapped to a Theme attribute in Android. The guidelines recommend using it in several areas such as a TabLayout backgrounds.
I cannot find an authoritative source about using this attribute in Android apps, but it seems that Material defines a large number of colors, as shown on this helpful page, but not all of them are mapped to Android Theme attributes. For instance, if you create a brand new single-Activity project in Android Studio and modify styles.xml as shown below:
<resources>
<!-- Base application theme. -->
<style name="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>
<!-- THIS THEME ATTRIBUTE IS NOT FOUND -->
<item name="colorPrimaryLight">#color/colorPrimary</item>
</style>
</resources>
The colorPrimaryLight attribute is not found by the compiler.
Therefore if you wanted to use it in your application you would presumably have to explicitly link to a color.xml resource. This seems to negate the benefit of the Theme system somewhat, but perhaps I am missing a trick.
I have a simple question, but I really don't get it. When we set a new style under material design, we use parent styles as follow:
<style name="AppTheme.Base" parent="Base.Theme.AppCompat.Light">
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
However, in some tutorials, I saw they insert the reference "android:" into the attribute, e.g.:
<item name="android:colorPrimaryDark">#color/colorPrimaryDark</item>
I know that the latter should be used for referencing every attribute in android, but I don't understand why in this case it is sometimes omitted and sometimes not.
It is omitted if you are using the Android V7 Support Library. In this case you use one of the Theme.AppCompat themes, instead of the Android theme. Take a look at Maintaining Compatibility.
It is depending on which compatibility they want:
using android: prefix they refer to a platform attribute, that is it will be effective only on devices where the attribute exist (e.g. API14+, API21+ etc)
using without android: prefix they refer to an Appcompat Library's attribute linked with the app project, that is it will be effective on all devices with API 7+
When styling ActionBarSherlock I was wondering when I have to use the prefixed attribute, when the non-prefixed attribute, and when both. For example:
<item name="actionBarStyle">#style/Widget.Styled.ActionBar</item>
<item name="android:actionBarStyle">#style/Widget.Styled.ActionBar</item>
I found this explanation on the ActionBarSherlock website:
Mirrored Attributes
Due to limitations in Android's theming system any theme customizations must be declared in two attributes. The normal android-prefixed attributes apply the theme to the native action bar and the unprefixed attributes are for the custom implementation. Since both theming APIs are exactly the same you need only reference your customizations twice rather than having to implement them twice.
The easiest way to convey exactly what this entails is with an example. The following is the full theme from the “Styled” example mentioned above:
<style name="Theme.Styled" parent="Theme.Sherlock.Light.DarkActionBar">
<item name="actionBarStyle">#style/Widget.Styled.ActionBar</item>
<item name="android:actionBarStyle">#style/Widget.Styled.ActionBar</item>
</style>
<style name="Widget.Styled.ActionBar" parent="Widget.Sherlock.Light.ActionBar.Solid.Inverse">
<item name="background">#drawable/bg_striped</item>
<item name="android:background">#drawable/bg_striped</item>
<item name="backgroundSplit">#drawable/bg_striped_split</item>
<item name="android:backgroundSplit">#drawable/bg_striped_split</item>
</style>
I thought, non-prefixed attributes only have to be used for attributes, that did not exist before API level 11. But why is there an android:background as well as a background attribute in the example? android:background exists since API level 1. Can someone please give some more details about these mirrored attributes?
From what I understand of the ActionBarSherlock documentation you quote, the android-prefixed attribute (which you would have been the only one to set if you used the "normal" ActionBar) is used when ActionBarSherlock uses the native version of ActionBar (that is, on devices running Android 3+, where it's available), and the non-prefixed version is used on older versions, when ActionBarSherlock actually has to use its own implementation of the ActionBar component.
In short, android-prefixed attributes are used by Android native features, and non-prefixed versions are used by custom components.
Anyway, it looks like you always have to set both prefixed and non-prefixed attribute when theming an ActionBarSherlock object.
Simple rule is anywhere you are inheriting from parent="Widget.Sherlock.etc" then you should have dual attributes.
The exception being direct styles like Text and Button don't as you are only passing your style to that TextView/Button directly, I would however always inherit from the parent/current style defined in the abs__styles.xml, that way you will always get the correct spacing etc..