Monday 2 February 2015

Difference between “?attr/” and “?android:attr/” in android

Hello Friends,

 Today i am going to share with you one of the concept of an android which is less documented. And the difference of it and in what scenario you can utilize it.


?android: --Is a reference to an item declared in the current Theme*. An example can show this best.  I like to think of these as style 'variables', or global attributes that can are set in the main Theme declaration.Let's say we've got a style that's currently being applied to a stock Widget, the ExpandableListView style. For our app, we want to override the groupIndicator and the childDivider styles.
First of all the basic:

@android: -- This is a reference to existing resource or previously declared style (or drawable or dimension, etc).

 <style name="Widget.Holo.ExpandableListView" parent="Widget.Holo.ListView">  
  <item name="groupIndicator">@android:drawable/expander_group_holo_dark</item>  
  ...  
  <item name="android:childDivider">?android:attr/listDivider</item>  
 </style>  

--groupIndicator is using an @android reference to a stock drawable.  To override this, we'll need have create a new style (that has a parent of Widget.Holo.ExpandableListView) and override the groupIndicator with a new drawable.  We'll then need to set the style on our ExpandableListView, or set the style for ExpandableListViews to use the new style or pass it to the style to the view directly via the constructor.

--childDivider is using a ?android attribute reference.  This is a lot easier to override.  In the main app Theme, add an item that sets this property.
 <style name="MyAppTheme" parent="android:Theme.Holo">  
    <item name="android:listDivider">@drawable/list_divider_custom</item>  
  </style>  

The listDivider has been updated for every style that's using the ?listDivider style attribute. Wherever a ?listDivider attribute has been referenced, will now be replaced with your custom list divider drawable.

To create your own layout attributes, you'll need to create an attribute for it first.

First declare the Theme styleable in attr.xml
 <declare-styleable name="Theme">  
   <attr name="customAttributeSize" format="reference|dimension">  
 </declare-styleable>  

Then add it to your project's themes.xml, and define a style for it.
 <style name="MyAppTheme" parent="android:Theme.Holo">  
   ...  
   <item name="customAttributeSize">24dp</item>  
   ...  
 </style>  
 <style name="TextAppearance.Custom" parent="TextAppearance">  
  <item name="android:textSize">?customAttributeSize</item>  
 </style>  

There's no need to namespace the reference with android: as it's a locally declared attribute.

For all the styles and themes that can be styled with an attribute, check out the source for attributes at attr.xml andthemes.xml.  The styles that compose a theme (and use attributes) are here.


?attr/xyz
Defines and refers to the value of an attribute which you have defined on your own in your application.

?android:attr/xyz

Refers to the values of an attribute which are already available in android built-in. More specifically, the ? implies an extra level of indirection. Think of it as dereferencing an attribute to fetch the resource it points to rather than referring to the attribute itself. You see this with ?android:attr/foo
Which is the best practice to use is depends on what properties you are using and if it is available in built-in android system then you can use it otherwise you can define on your own.

No comments:

Post a Comment