I am new to android and have a question about the styles.xml file.
Each item for example this
<item name="android:background">#color/black</item>
works both with "android:background" and with just "background".
What is the android: prefix there for?
When creating your own styles, you should always extend an existing style from the framework or support library so that you maintain compatibility with platform UI styles. To extend a style, specify the style you want to extend with the parent attribute. You can then override the inherited style attributes and add new ones.
For example, you can inherit the Android platform's default text appearance and modify it as follows:
<style name="GreenText" parent="#android:style/TextAppearance">
<item name="android:textColor">#00FF00</item>
</style>
However, you should always inherit your core app styles from the Android Support Library.
But if you don't inherit them from the android support library then too things will work the same!
Source: Explanation text and code taken from: https://developer.android.com/guide/topics/ui/look-and-feel/themes
You can read more about Styles and Themes from the above doc, from where I took the example to explain you!
I know that
we have not to use parent attribute. We prefix one style to another
style separating by a period(.)
so in this style, does it have a circular inheritance?
<style name="TextAppearance.A" parent="TextAppearance.A.B">
<item name="android:textAlignment">viewStart</item>
<item name="android:gravity">start</item>
</style>
TextAppearance.A.B inherits from TextAppearance.A because of android dots' syntax.
but TextAppearance.A inherits from TextAppearance.A.B because of android paretn syntax.
Is it really a problem?
Technically As per Android Documentation I dont think this is possible,
Because this will lead to duplication of style, If you refer to same as Diamond Problem it will be one of those, also android prevents you from inheriting from more than one style.
Further Imagine if you have one attribute which is defined in style A also in Style B, it will be a problem at compile time that which attribute to choose from both.
For More Details please refer to android documentation
https://developer.android.com/guide/topics/ui/look-and-feel/themes
I know that
we have not to use parent attribute. We prefix one style to another
style separating by a period(.)
so in this style, does it have a circular inheritance?
<style name="TextAppearance.A" parent="TextAppearance.A.B">
<item name="android:textAlignment">viewStart</item>
<item name="android:gravity">start</item>
</style>
TextAppearance.A.B inherits from TextAppearance.A because of android dots' syntax.
but TextAppearance.A inherits from TextAppearance.A.B because of android paretn syntax.
Is it really a problem?
Technically As per Android Documentation I dont think this is possible,
Because this will lead to duplication of style, If you refer to same as Diamond Problem it will be one of those, also android prevents you from inheriting from more than one style.
Further Imagine if you have one attribute which is defined in style A also in Style B, it will be a problem at compile time that which attribute to choose from both.
For More Details please refer to android documentation
https://developer.android.com/guide/topics/ui/look-and-feel/themes
I know that
we have not to use parent attribute. We prefix one style to another
style separating by a period(.)
so in this style, does it have a circular inheritance?
<style name="TextAppearance.A" parent="TextAppearance.A.B">
<item name="android:textAlignment">viewStart</item>
<item name="android:gravity">start</item>
</style>
TextAppearance.A.B inherits from TextAppearance.A because of android dots' syntax.
but TextAppearance.A inherits from TextAppearance.A.B because of android paretn syntax.
Is it really a problem?
Technically As per Android Documentation I dont think this is possible,
Because this will lead to duplication of style, If you refer to same as Diamond Problem it will be one of those, also android prevents you from inheriting from more than one style.
Further Imagine if you have one attribute which is defined in style A also in Style B, it will be a problem at compile time that which attribute to choose from both.
For More Details please refer to android documentation
https://developer.android.com/guide/topics/ui/look-and-feel/themes
UPDATE: As pointed out in the comments, 'Widget.AppCompat.EditText' is the correct parent style for an AppCompatEditText subclass. In my case, the real issue was I had forgotten to assign a value to our control's default style attribute in our theme, so our control wasn't getting any style to use as a default.
However, this question still could use an answer as to how one properly identifies which style to use as a parent when defining your own default styles when subclassing the standard controls. As such, I've also renamed its title.
As such, I'm leaving this open in hopes someone can answer that question since it will help any who wish to do something similar.
We're trying to define a common look-and-feel for all AppCompatEditText controls used throughout the app. As such, rather than having to manually apply the 'style' attribute on each usage, we're instead trying to replace the default style with our own.
Replacing the default style is actually the easy part. What isn't is knowing what the parent style for our style should be set to so we still have all aspects of the original style which we haven't explicitly overwritten with those in ours.
Digging in the source code for AppCompatEditText, it shows the default style to be stored in R.attr.editTextStyle but I'm not sure where now to look to see what value is stored in it.
Experimenting too didn't get us anywhere. No matter what we have tried so far, we lose the default appearance completely. No underline, no background, no padding, nothing. Just the values we've set, which means it's not picking up the parent style.
We've tried the following without success...
<style name="ZinEditText" parent="android:Widget.EditText">
<item name="zinTypeface">light</item>
<item name="android:textSize">#dimen/defaultTextSize</item>
<item name="android:lineSpacingMultiplier">#dimen/defaultLineSpacing</item>
</style>
<style name="ZinEditText" parent="Widget.AppCompat.EditText">
<item name="zinTypeface">light</item>
<item name="android:textSize">#dimen/defaultTextSize</item>
<item name="android:lineSpacingMultiplier">#dimen/defaultLineSpacing</item>
</style>
<style name="ZinEditText" parent="Base.V7.Widget.AppCompat.EditText">
<item name="zinTypeface">light</item>
<item name="android:textSize">#dimen/defaultTextSize</item>
<item name="android:lineSpacingMultiplier">#dimen/defaultLineSpacing</item>
</style>
<style name="ZinEditText" parent="Widget.Holo.EditText">
<item name="zinTypeface">light</item>
<item name="android:textSize">#dimen/defaultTextSize</item>
<item name="android:lineSpacingMultiplier">#dimen/defaultLineSpacing</item>
</style>
As I said, none of the above seemed to work.
So how does one find the actual parent style to use?
To address the immediate issue, the default style for an AppCompatEditText is Widget.AppCompat.EditText. The second example you've shown is the correct one:
<style name="ZinEditText" parent="Widget.AppCompat.EditText">
...
This needs to be set as the editTextStyle in your app theme.
<style name="AppTheme" parent="#style/Theme.AppCompat">
<item name="editTextStyle">#style/ZinEditText</item>
...
Finding these default styles and attributes is not well documented anywhere officially, as far as I'm aware. The official documentation for Styles and Themes simply directs one to the various R.attr pages for the framework and support packages, to "discover" what's available. However, a generally reliable way to find this for most Views that allow a default style is to inspect the source code.
A View subclass will often implement at least three constructors: one that takes only a Context; one that takes a Context and an AttributeSet; and one that takes a Context, an AttributeSet, and an int for defStyleAttr, a default style attribute. This attribute is what we're looking for. It will usually have a sensible name, like editTextStyle, textViewStyle, checkboxStyle, etc. If you already know the name, you can skip checking the View class for it.
In Views that chain their constructors, this attribute will be normally be in the call to the three-parameter constructor from the two-parameter one. In AppCompatEditText, we can see that the name of this attribute is editTextStyle.
public AppCompatEditText(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.editTextStyle);
}
After we've got the name for the attribute, we then head to the res/values/ directory for the platform or support package the View is in. The default value will be in the relevant themes*.xml file for your app's parent theme.
For the platform themes, there is a base themes.xml, and a few others for specific theme versions, such as Holo and Material.
For support library Views, these theme files will be under the package-specific res/values/ directory, and the default attribute value may be in themes.xml or themes_base.xml.
In v7 appcompat, our app's exact parent theme is likely in v7/appcompat/res/values/themes.xml, though most of the themes there are just direct aliases for base themes; i.e., they don't override any of their parents' attribute values. The default for AppCompatEditText is actually in v7/appcompat/res/values/themes_base.xml. There are separate entries for different themes - the regular, and the light - but they are both the same.
<item name="editTextStyle">#style/Widget.AppCompat.EditText</item>
This is enough to determine which style to use as our parent, but should we want to check out the style specifics, we can then refer to v7/appcompat/res/values/styles.xml, where we find that style's parent:
<style name="Widget.AppCompat.EditText" parent="Base.Widget.AppCompat.EditText"/>
which leads us to v7/appcompat/res/values/styles_base.xml:
<style name="Base.Widget.AppCompat.EditText" parent="Base.V7.Widget.AppCompat.EditText" />
<style name="Base.V7.Widget.AppCompat.EditText" parent="android:Widget.EditText">
<item name="android:background">?attr/editTextBackground</item>
<item name="android:textColor">?attr/editTextColor</item>
<item name="android:textAppearance">?android:attr/textAppearanceMediumInverse</item>
</style>