Custom attributes
satya - Tue May 22 2012 16:05:59 GMT-0400 (Eastern Daylight Time)
If I inherit from an existing Android class
and if the class is already allowed in an xml file, they you can just use your class in its place with a default constructor and the same allowed attributes.
satya - Tue May 22 2012 16:06:34 GMT-0400 (Eastern Daylight Time)
How can I have my own custom attributes for an android custom component?
How can I have my own custom attributes for an android custom component?
Search for: How can I have my own custom attributes for an android custom component?
satya - Tue May 22 2012 20:00:37 GMT-0400 (Eastern Daylight Time)
an attributeset seem to be a way to read from XML resources
an attributeset seem to be a way to read from XML resources
satya - Tue May 22 2012 20:02:25 GMT-0400 (Eastern Daylight Time)
Here is what the docs say
A collection of attributes, as found associated with a tag in an XML document
satya - Tue May 22 2012 20:02:47 GMT-0400 (Eastern Daylight Time)
So they relate to a 'tag' and not to the whole xml
So they relate to a 'tag' and not to the whole xml
satya - Tue May 22 2012 20:09:44 GMT-0400 (Eastern Daylight Time)
Understand TypedArray
satya - Tue May 22 2012 20:11:33 GMT-0400 (Eastern Daylight Time)
TypedArray recycle
TypedArray recycle
satya - Tue May 22 2012 21:41:55 GMT-0400 (Eastern Daylight Time)
what is attrs.xml
what is attrs.xml
satya - Tue May 22 2012 21:43:06 GMT-0400 (Eastern Daylight Time)
Here is an example of attrs.xml
<resources>
<declare-styleable name="ApplicationsStackLayout">
<attr name="stackOrientation">
<enum name="horizontal" value="0" />
<enum name="vertical" value="1" />
</attr>
<attr name="marginLeft" format="dimension" />
<attr name="marginTop" format="dimension" />
<attr name="marginRight" format="dimension" />
<attr name="marginBottom" format="dimension" />
</declare-styleable>
</resources>
satya - Tue May 22 2012 21:44:18 GMT-0400 (Eastern Daylight Time)
This article may throw some light
satya - Tue May 22 2012 21:46:01 GMT-0400 (Eastern Daylight Time)
understand declare-styleable android tag
understand declare-styleable android tag
satya - Tue May 22 2012 21:48:34 GMT-0400 (Eastern Daylight Time)
Somehow this tag points to a classname
when that class is constructed the attributes are passed to it. and then you use a typed array to get them.
satya - Tue May 22 2012 21:48:49 GMT-0400 (Eastern Daylight Time)
why not the full path to the classname?
why not the full path to the classname?
satya - Tue May 22 2012 22:04:20 GMT-0400 (Eastern Daylight Time)
declare-styleable
declare-styleable
Search Google for: declare-styleable
Search Android Developers Group for: declare-styleable
Search Android Beginers Group for: declare-styleable
satya - Tue May 22 2012 22:27:35 GMT-0400 (Eastern Daylight Time)
declare-styleable classname implied
declare-styleable classname implied
satya - Tue May 22 2012 22:32:46 GMT-0400 (Eastern Daylight Time)
what are the restrictions on the declare-styleable name attribute?
what are the restrictions on the declare-styleable name attribute?
Search for: what are the restrictions on the declare-styleable name attribute?
satya - Tue May 22 2012 22:36:22 GMT-0400 (Eastern Daylight Time)
This is a reasonable ref from stackoverflow
satya - Tue May 22 2012 22:38:26 GMT-0400 (Eastern Daylight Time)
Ok here are the restrictions on the declare-styleable name attribute
it has to be a classname minus the package
the namespace must be the entire deeply nested package minus the classname
satya - Tue May 22 2012 22:53:38 GMT-0400 (Eastern Daylight Time)
may be...I am still researching.
may be...I am still researching.
satya - Tue May 22 2012 22:55:10 GMT-0400 (Eastern Daylight Time)
Here are key facts
declare-style first
give it a classname
provide attributes and their types
Provide a namespace in the layout xml files
Use generated R.sytleable.your-custom-view constants in java code
satya - Wed May 23 2012 12:45:36 GMT-0400 (Eastern Daylight Time)
declare-styleable name class just a convention
declare-styleable name class just a convention
satya - Wed May 23 2012 12:48:21 GMT-0400 (Eastern Daylight Time)
Here is a discussion of custom attributes across libraries
satya - Wed May 23 2012 12:51:44 GMT-0400 (Eastern Daylight Time)
No that link does ask the right question, it was related to sub packages, not libraries
No that link does ask the right question, it was related to sub packages, not libraries
satya - Wed May 23 2012 15:24:57 GMT-0400 (Eastern Daylight Time)
Here is an example of attrs.xml for api samples from android
<resources>
<!-- These are the attributes that we want to retrieve from the theme
in app/PreferencesFromCode.java -->
<declare-styleable name="TogglePrefAttrs">
<attr name="android:preferenceLayoutChild" />
</declare-styleable>
<!-- These are the attributes that we want to retrieve from the theme
in view/Gallery1.java -->
<declare-styleable name="Gallery1">
<attr name="android:galleryItemBackground" />
</declare-styleable>
<declare-styleable name="LabelView">
<attr name="text" format="string" />
<attr name="textColor" format="color" />
<attr name="textSize" format="dimension" />
</declare-styleable>
<!-- These are attributes used with 'DraggableDot' drawables in
view/DragAndDropActivity.java and view/DraggableDot.java -->
<declare-styleable name="DraggableDot">
<attr name="radius" format="dimension" />
<attr name="legend" format="string" />
<attr name="anr">
<enum name="none" value="0" />
<enum name="thumbnail" value="1" />
<enum name="drop" value="2" />
</attr>
</declare-styleable>
<!-- These are the attributes that we want to retrieve for
app/FragmentArguments.java -->
<declare-styleable name="FragmentArguments">
<attr name="android:label" />
</declare-styleable>
</resources>
satya - Wed May 23 2012 15:27:52 GMT-0400 (Eastern Daylight Time)
The name of the declare-styleable appears to be arbitrary and doesn't have to be a classname
<resources>
<item type="id" name="menu_da_clear"/>
<attr name="a1" format="string"></attr>
<declare-styleable name="SomeArbitraryName">
<attr name="a2" format="string" />
</declare-styleable>
</resources>
satya - Wed May 23 2012 15:32:00 GMT-0400 (Eastern Daylight Time)
This creates the following constants
R.attr.a1
R.attr.a2
R.styleable.SomeAttributeName
//this is an int araay of 1
//the first element value is same
//as R.attr.a2
R.styleable.SomeAttributeName_a2
satya - Wed May 23 2012 22:49:57 GMT-0400 (Eastern Daylight Time)
Here is what the generated doc says about R.attr class
Must be a string value, using '\\;' to escape characters such as '\\n' or '\\uxxxx' for a unicode character.
This may also be a reference to a resource (in the form
"@[package:]type:name
") or
theme attribute (in the form
"?[package:][type:]name
")
containing a value of this type.
satya - Wed May 23 2012 22:51:30 GMT-0400 (Eastern Daylight Time)
Sorry that generated comment was about R.attr.a1
which in the above xml defined as a string.
satya - Wed May 23 2012 22:53:33 GMT-0400 (Eastern Daylight Time)
Notice how the name of the 'styleable' is arbitrary
I could have given any continuous string name in it. It doesnt have to be a classname at all. On the internet you may perceive this as a classname. But that is quite likely a convention.
In the example above the name "SomeAttributeName" doesn't point to any class. I did not even create such a class. Compiler did not seem to care.
satya - Wed May 23 2012 23:12:16 GMT-0400 (Eastern Daylight Time)
This would be wrong: Interesting
<resources>
<item type="id" name="menu_da_clear"/>
<attr name="a1" format="string"></attr>
<attr name="a2" format="dimension"/>
<declare-styleable name="SomeArbitraryName">
<attr name="a2" format="string" />
</declare-styleable>
</resources>
satya - Wed May 23 2012 23:13:28 GMT-0400 (Eastern Daylight Time)
It will be wrong to name two attributes with the same name
even though one is under root and one is under a particular styleable section.
satya - Wed May 23 2012 23:19:58 GMT-0400 (Eastern Daylight Time)
valid android attr format types
valid android attr format types
satya - Wed May 23 2012 23:21:47 GMT-0400 (Eastern Daylight Time)
Here is the first link off of Google
satya - Wed May 23 2012 23:23:34 GMT-0400 (Eastern Daylight Time)
The above link is from Bill Woody
Bill has indicated that this is in the file AttributeFormat.java
satya - Wed May 23 2012 23:23:46 GMT-0400 (Eastern Daylight Time)
AttributeFormat.java
AttributeFormat.java
satya - Wed May 23 2012 23:24:34 GMT-0400 (Eastern Daylight Time)
Here are the possible values
reference
string
color
dimension
boolean
integer
float
fraction
enum
flag
satya - Wed May 23 2012 23:25:54 GMT-0400 (Eastern Daylight Time)
Also note these types are case sensitive
Also note these types are case sensitive
satya - Wed May 23 2012 23:45:49 GMT-0400 (Eastern Daylight Time)
The styleable constant R.styleable.SomeAttributeName
This is an array of resource identifiers pointing to the "attribute" object identified by "attr" tag. Each such object would have name, format, etc.
satya - Wed May 23 2012 23:46:40 GMT-0400 (Eastern Daylight Time)
what is the meaning of android colon in an attribute name?
what is the meaning of android colon in an attribute name?
Search for: what is the meaning of android colon in an attribute name?
satya - Wed May 23 2012 23:52:23 GMT-0400 (Eastern Daylight Time)
This is a really nice article and most comprehensive I have seen so far?
This is a really nice article and most comprehensive I have seen so far?
satya - Wed May 23 2012 23:55:44 GMT-0400 (Eastern Daylight Time)
Looks like the documentation is in the root attrs.xml:
core/res/res/values/attrs.xml
satya - Wed May 23 2012 23:57:56 GMT-0400 (Eastern Daylight Time)
Looks like there is a concept of reuse as well
<resources>
<item type="id" name="menu_da_clear"/>
<attr name="a1" format="integer"></attr>
<declare-styleable name="SomeArbitraryName">
<attr name="a2" format="string" />
<attr name="a1"/>
</declare-styleable>
</resources>
satya - Wed May 23 2012 23:58:08 GMT-0400 (Eastern Daylight Time)
Notice how 'a1' is reused with out the format
Notice how 'a1' is reused with out the format
satya - Wed May 23 2012 23:58:42 GMT-0400 (Eastern Daylight Time)
if the name says 'android:some-name' then
we use the corresponding attribute from the android name space.
satya - Wed May 23 2012 23:59:22 GMT-0400 (Eastern Daylight Time)
Example
<declare-styleable name="TogglePrefAttrs">
<attr name="android:preferenceLayoutChild" />
</declare-styleable>
satya - Sat May 26 2012 12:50:47 GMT-0400 (Eastern Daylight Time)
Here is a name space spec
xmlns:your-ns="http://schemas.android.com/apk/res/com.example.yourpackage
satya - Sat May 26 2012 12:54:46 GMT-0400 (Eastern Daylight Time)
The specs for this name space is same as any XML namespace
this means you can pretty much indicate whatever you want. It is only convention (probably a good one) that it points to your package name.
why am I saying this? because I thought may be Android is doing something special using this name to make sure the attributes are defined on the class you have indicated. It doesn't.
satya - Sat May 26 2012 12:57:09 GMT-0400 (Eastern Daylight Time)
However for your name space give a name that is not too cryptic
xmlns:apptemplate="http://schemas.android.com/apk/res/com.ai.android.book.apptemplate2"
Either a package name or a specific classname if there are lot of custom classes. If you only have a handful of classes your package name might work as well.
satya - Sat May 26 2012 19:39:04 GMT-0400 (Eastern Daylight Time)
Apparently this is wrong
<TextView
android:id="@+id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Debut Text Appears here"
apptemplate:custom_text="Custom Hello"
/>
satya - Sat May 26 2012 19:43:42 GMT-0400 (Eastern Daylight Time)
The restriction is
Android doesn't want you to add additional attributes to your class unless there is an "id" generated through "R".
Why?
Probably because, without an integer or a constant, you will be forced to write that can be brittle. Ex:
AttribSet.getValue("apptemplate:custom_text");
I know. the method names are all wrong and all, but you get the idea.
So Android wants you to define this new string reference "custom_text" as a pre-known attribute with a proper id and possibly a type (I suppose as an added convenience)
satya - Sat May 26 2012 19:44:47 GMT-0400 (Eastern Daylight Time)
If you notice I have added this to an Android view, the result is same for a custom view as well
<com.ai.android.book.apptemplate2.MyTextView
android:id="@+id/custom_text_id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Debut Text Appears here"
apptemplate:custom_text="Custom Hello"
/>
satya - Sat May 26 2012 19:46:47 GMT-0400 (Eastern Daylight Time)
I can get rid of the error by doing
<resources>
<item type="id" name="menu_da_clear"/>
<attr name="a1" format="integer"></attr>
<declare-styleable name="SomeArbitraryName">
<attr name="a2" format="string" />
<attr name="a1"/>
<attr name="custom_text" format="string"/>
</declare-styleable>
</resources>
satya - Sat May 26 2012 19:47:16 GMT-0400 (Eastern Daylight Time)
I don't think it matters where I add that custom_text attribute
it can be outside of a styleable or inside.
satya - Sat May 26 2012 19:56:40 GMT-0400 (Eastern Daylight Time)
what is index of an AttributeSet?
what is index of an AttributeSet?
satya - Sat May 26 2012 20:11:26 GMT-0400 (Eastern Daylight Time)
attribute set namespace null
attribute set namespace null
satya - Sat May 26 2012 20:28:41 GMT-0400 (Eastern Daylight Time)
Here is an example of custom attributes I am playing with
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:apptemplate="http://schemas.android.com/apk/res/com.ai.android.book.apptemplate2"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.ai.android.book.apptemplate2.MyTextView
android:id="@+id/custom_text_id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Debut Text Appears here"
apptemplate:custom_text="Custom Hello"
/>
<TextView
android:id="@+id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Debut Text Appears here"
/>
</LinearLayout>
satya - Sat May 26 2012 20:29:45 GMT-0400 (Eastern Daylight Time)
The following returns a good value
String namespace="http://schemas.android.com/apk/res/com.ai.android.book.apptemplate2";
String mytext = attrs.getAttributeValue(namespace, "custom_text");
satya - Sat May 26 2012 20:30:12 GMT-0400 (Eastern Daylight Time)
attrs.getAttributeCount() returns 5
attrs.getAttributeCount() returns 5
satya - Sat May 26 2012 20:36:13 GMT-0400 (Eastern Daylight Time)
The attributeset is implemented by
android.content.res.XmlBlock$Parser
satya - Sat May 26 2012 20:36:58 GMT-0400 (Eastern Daylight Time)
what is the index in the attribute set?
for(int i=0;i<attrs.getAttributeCount();i++)
{
Log.d("bla", "value:" + attrs.getAttributeValue(i));
}
satya - Sat May 26 2012 20:37:24 GMT-0400 (Eastern Daylight Time)
This will print
value:@2130968577
value:-1
value:-2
value:Debut Text Appears here
value:Custom Hello
satya - Sat May 26 2012 20:38:27 GMT-0400 (Eastern Daylight Time)
So clearly one should use the recommended way to get your attributes
I am just playing around to see the behavior of attributeset. Of course you will see soon the right way.
satya - Sat May 26 2012 20:48:27 GMT-0400 (Eastern Daylight Time)
So what is the right way? Use Resources.Theme.obtainStyledAttributes
So what is the right way? Use Resources.Theme.obtainStyledAttributes
satya - Sat May 26 2012 21:02:00 GMT-0400 (Eastern Daylight Time)
Let's see what happened to our styleable
public static final int[] SomeArbitraryName = {
0x7f010000, 0x7f010001, 0x7f010002
};
what do you think the three values in this array are? well they are the identifiers for
a1
a2
custom_text
Ta...daa...
satya - Sun May 27 2012 17:45:46 GMT-0400 (Eastern Daylight Time)
So here is the pattern that is recommended
TypedArray t = ctx.obtainStyledAttributes(attrs,R.styleable.SomeArbitraryName);
mytext = t.getString(R.styleable.SomeArbitraryName_custom_text);
t.recycle();
satya - Sun May 27 2012 17:48:36 GMT-0400 (Eastern Daylight Time)
Line1 above
This method takes the incoming attribute set and a list of attribute ids as defined in the attrs.xml. this list is given as an integer array
for convenience the ADK has generated an id array when you put a few attributes under declare-styleable. This array is indicated by
R.styleable.SomeAttributeName
satya - Sun May 27 2012 17:50:43 GMT-0400 (Eastern Daylight Time)
Line2
mytext = t.getString(R.styleable.SomeArbitraryName_custom_text);
In here we are asking the typed array to give us the value of custom_text by indicating where this item is in the typed array. the place of this item in the array is indicated by the generated constant
somearbitraryname_custom_text
satya - Sun May 27 2012 17:51:35 GMT-0400 (Eastern Daylight Time)
Line2 recycle
Finally the spec says we have to indicate the completion of use of the typedarray object so that it can be recycled or its memory managed better.
satya - Tue Sep 18 2012 08:59:43 GMT-0400 (Eastern Daylight Time)
All of this research is consolidated in to an article which is at this link
All of this research is consolidated in to an article which is at this link