I know how to create custom attributes for views, for example:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="SomeViewsCustomAttrs">
<attr name="someAttr" format="dimension" />
<attr name="anotherAttr" format="boolean" />
</declare-styleable>
</resources>
I am wondering if there is a way to add documentation to these custom attrs. While editing layouts in the XML editor, you can get tooltips that describe what the attrs are. As an example, if you are typing android:layout_width= it will give you the following information, "Specifies the basic width of the view. [dimension, enum]"
Is there a way to provide that for your own attrs?
Thanks
Add XML comment to every element:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="SomeViewsCustomAttrs">
<!-- Default highlight color for items that are pressed. -->
<attr name="colorPressedHighlight" format="color" />
<!-- Default highlight color for items that are long-pressed. -->
<attr name="colorLongPressedHighlight" format="color" />
</declare-styleable>
</resources>
And in the Java Doc in the Java source file of your view link to the attributes like this (example from TextView):
* See {#link android.R.styleable#TextView TextView Attributes}, {#link android.R.styleable#View View Attributes}
You need to write constructors in code and then link them to the xml. Read this for more info.
Related
Update: There were 2 custom attributes defined in CustomTextView.. If both are defined in xml it works fine.. If first is missing it does not give any value for 2nd also...
<com.mycompany.projectname.MyCustomView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:extraColor="?someColor"
/>
Here someColor is another color attr which varies for different themes..
I need value of extraColor custom attribute in MyCustomView class...
Currently obtaining it as below:
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomTextView, defStyleAttr, 0);
a.getColorStateList() does not work here...
CustomTextView defined as:
<declare-styleable name="CustomTextView">
<attr name="state" format="boolean" />
<attr name="extraColor" format="reference|color" />
</declare-styleable>
Update: There were 2 custom attributes defined in CustomTextView..
If both are defined in xml it works fine.. If first is missing it does not give any value for 2nd also...
Could you try that one..
a.getColor(R.styleable.CustomTextView_extraColor, Color.WHITE)
use only either reference or color
<declare-styleable name="CustomTextView">
<attr name="extraColor" format="reference" />
</declare-styleable>
And then if it is reference get it like,
a. getColorStateList(R.styleable.CustomTextView_extraColor);
if it is color then,
a. getColor(R.styleable.CustomTextView_extraColor, Color.WHITE);
In addition to what others have said, it looks like the naming is inconsistent (copy+paste error?): in most of the code you posted, your refer to a CustomTextView, but in the XML, you use MyCustomView.
Try changing your XML:
<com.mycompany.projectname.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:extraColor="?someColor"
/>
In my Android project I have a couple of custom components that use custom attributes.
The attrs.xml file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<resources >
<declare-styleable name = "TextBox">
<attr name = "font" format = "string"/>
</declare-styleable>
<declare-styleable name = "ButtonBox">
<attr name = "font" format = "string"/>
</declare-styleable>
</resources>
I am pulling in the attributes just fine in the custom component, but when I go to run the code I see the following error.
Error: Found item Attr/font more than one time
Error: Execution failed for task ':app:mergeDebugResources'.
It shouldn't make a difference that there are similar attribute names in two different declare-styleable resources correct?
If you have any help it would be greatly appreciated, thank you!
As you can see here, the attr itself can have multiple properties and can be defined only once and you can configure multiple details inside it.
So you should give it different names or, since they have the same properties, use only one declare-styable for both.
Check out this link too, there's a good example.
Here is how it should be:
<?xml version="1.0" encoding="utf-8"?>
<resources >
<declare-styleable name="Box">
<attr name="font" format="string"/>
</declare-styleable>
</resources>
You can use Box on text, button, etc.
Android — Custom Views: same Attribute on multiple Custom Views
You may have tried something like the code below in your attrs.xml:
'''
<resources>
<declare-styleable name="MyComponent1">
<attr name="myAttr" format="string" />
</declare-styleable>
<declare-styleable name="MyComponent2">
<attr name="myAttr" format="string" />
</declare-styleable>
</resources>
'''
But this does not work, and we get an Error:
Found item Attr/myAttr more than one time.
How do native views handle that?
Native Views have the same attribute names and don’t suffer from this problem.
Let’s sneak into their code and see how these attributes are declared.
Looking into their code, we can see that they create the attr tag outside declare-styleable, and then, inside of it you just need to reference it only by its name, there is no need to declare format again.
Our code should be just like that:
<resources>
<attr name="myAttr" format="string" />
<declare-styleable name="MyComponent1">
<attr name="myAttr" />
</declare-styleable>
<declare-styleable name="MyComponent2">
<attr name="myAttr" />
</declare-styleable>
</resources>
can also read this fantastic medium paper :
same Attribute on multiple Custom Views
So I have defined a custom attribute:
<resources>
<attr name="filterColor" format="color"/>
</resources>
I did not declare it in an to reuse it in other custom views.
However, I am not able to use it like so
<SomeView
app:filterColor="#color/my_color"/>
Nor am I able to obtain it from AttributeSet
final TypedArray a = getContext().obtainStyledAttributes(attrs, new int[]{R.attr.filterColor});
It's driving me crazy - why are we allowed to declare global custom Attributes then if we can't use them?
If nothing else, your XML appears to be missing the <declare-styleable> element:
<resources>
<declare-styleable name="ColorMixer">
<attr name="color" format="color" />
</declare-styleable>
</resources>
(pulled from this library project)
The name in declare-styleable should be the class name of the view that will use the attribute (SomeView in your case).
This is covered in the documentation.
If I have the following setup:
public class ABCView extends View {
//implementation here
}
With the following custom attributes:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name = "ABCView" >
<attr name="foo" format="boolean"/>
</declare-styleable>
</resources>
If I want to subclass this View with another one, but still be able to specify the values of custom attributes in XML, how can I do that?
public class DEFView extends ABCView {
//implementation here
}
But when I attempt to use the child view in XML, I get an error - it doesn't recognize that the attribute applies, as it doesn't seem to know about the relationship between the java classes. How can I handle this?
Since XML won't about java class hierarchy, you might want to specify the custom attributes explicitly for the sub-sub-classed view as well.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name = "DEFView" >
<attr name="foo" format="boolean"/>
</declare-styleable>
</resources>
I follow this guide to make a custom ListView for my app. The tutorial uses a namespace called ottasee, which should be defined as a xml-namespace inside the element. So here is some of my code:
<com.my.app.Layout.CustomListView
xmlns:ottasee="what_should_i_put_here?"
android:id="#+id/lastCases"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:divider="#null"
android:scrollbars="none"
ottasee:dropShadowBottom="true"
ottasee:dropshadowrightsrc="#drawable/drop_shadow"
/>
I can see that the attributes ottasee:dropShadowBottom and ottasee:dropshadowrightsrc are part of my attrs.xml in the values folder. Like this:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<declare-styleable name="DropShadowListView">
<attr format="boolean" name="dropShadowLeft"></attr>
<attr format="reference" name="dropShadowLeftSrc"></attr>
<attr format="boolean" name="dropShadowRight"></attr>
<attr format="reference" name="dropShadowRightSrc"></attr>
<attr format="boolean" name="dropShadowTop"></attr>
<attr format="reference" name="dropShadowTopSrc"></attr>
<attr format="boolean" name="dropShadowBottom"></attr>
<attr format="reference" name="dropShadowBottomSrc"></attr>
</declare-styleable>
</resources>
How should I define the xml namespace for the ListView in order to grab the attributes from the attrs.xml file?
Thanks!
EDIT
My CustomListView is under the package com.my.app.Layout and I tried to declare the ns this way: xmlns:ottasee="http://schemas.android.com/apk/res/com.my.app.Layout
But I only get an error in my xml file:
Multiple annotations found at this line:
- error: No resource identifier found for attribute 'dropShadowBottom' in package
'com.my.app.Layout'
- error: No resource identifier found for attribute 'dropshadowrightsrc' in package
'com.my.app.Layout'
How can I accomplish setting the right ns?
You should add the following the following to include the necessary attributes to your namespace:
xmlns:ottasee ="http://schemas.android.com/apk/res-auto"
Slightly different to #budius's answer as it will auto-resolve the package name for you.
usually the XML editor do it for you, I've even never worried, but it's like that:
xmlns:ottasee="http://schemas.android.com/apk/res/com.your.package.name"