Custom attributes

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.

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?

AttributeSet api

an attributeset seem to be a way to read from XML resources

A collection of attributes, as found associated with a tag in an XML document

So they relate to a 'tag' and not to the whole xml

Understand TypedArray

TypedArray recycle

Search for: TypedArray recycle

what is attrs.xml

Search for: what is 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>

This article may throw some light

understand declare-styleable android tag

Search for: understand declare-styleable android tag

when that class is constructed the attributes are passed to it. and then you use a typed array to get them.

why not the full path to the classname?

declare-styleable

Search Google for: declare-styleable

Search Android Developers Group for: declare-styleable

Search Android Beginers Group for: declare-styleable

Search Google Code for: declare-styleable

Search Android Issues Database for: declare-styleable

declare-styleable classname implied

Search for: declare-styleable classname implied

what are the restrictions on the declare-styleable name attribute?

Search for: what are the restrictions on the declare-styleable name attribute?

This is a reasonable ref from stackoverflow


it has to be a classname minus the package
the namespace must be the entire deeply nested package minus the classname

may be...I am still researching.


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

declare-styleable name class just a convention

Search for: declare-styleable name class just a convention

Here is a discussion of custom attributes across libraries

No that link does ask the right question, it was related to sub packages, not libraries


<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>

<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>

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

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.

which in the above xml defined as a string.

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.


<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>

even though one is under root and one is under a particular styleable section.

valid android attr format types

Search for: valid android attr format types

Here is the first link off of Google

Bill has indicated that this is in the file AttributeFormat.java

AttributeFormat.java

Search for: AttributeFormat.java


reference
string
color
dimension
boolean
integer
float
fraction
enum
flag

Also note these types are case sensitive

This is an array of resource identifiers pointing to the "attribute" object identified by "attr" tag. Each such object would have name, format, etc.

what is the meaning of android colon in an attribute name?

Search for: what is the meaning of android colon in an attribute name?

This is a really nice article and most comprehensive I have seen so far?


core/res/res/values/attrs.xml

<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>

Notice how 'a1' is reused with out the format

we use the corresponding attribute from the android name space.


<declare-styleable name="TogglePrefAttrs">
        <attr name="android:preferenceLayoutChild" />
    </declare-styleable>

xmlns:your-ns="http://schemas.android.com/apk/res/com.example.yourpackage

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.


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.


<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"
    />

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)


<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"
    />

<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>

it can be outside of a styleable or inside.

what is index of an AttributeSet?

Search for: what is index of an AttributeSet?

attribute set namespace null

Search for: attribute set namespace null


<?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>

String namespace="http://schemas.android.com/apk/res/com.ai.android.book.apptemplate2";
String mytext = attrs.getAttributeValue(namespace, "custom_text");

attrs.getAttributeCount() returns 5


android.content.res.XmlBlock$Parser

for(int i=0;i<attrs.getAttributeCount();i++)
{
    Log.d("bla", "value:" + attrs.getAttributeValue(i));
}

value:@2130968577
value:-1
value:-2
value:Debut Text Appears here
value:Custom Hello

I am just playing around to see the behavior of attributeset. Of course you will see soon the right way.

So what is the right way? Use Resources.Theme.obtainStyledAttributes


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...


TypedArray t = ctx.obtainStyledAttributes(attrs,R.styleable.SomeArbitraryName);
mytext = t.getString(R.styleable.SomeArbitraryName_custom_text);
t.recycle();

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

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

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.

All of this research is consolidated in to an article which is at this link