I'm reading Beginning Android 4 Development and in chapter 5 it talks about Gallery and ImageVievs and introduces the declare-styleable XML tag without explaining its purpose.. I tried to find some info also on the reference, without luck.. For example we have the following:
res/values/attrs.xml
<?xml version=”1.0” encoding=”utf-8”?>
<resources>
<declare-styleable name=”Gallery1”>
<attr name=”android:galleryItemBackground” />
</declare-styleable>
</resources>
example.java
public class GalleryActivity extends Activity {
[...]
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Gallery gallery = (Gallery) findViewById(R.id.gallery1);
gallery.setAdapter(new ImageAdapter(this));
[...]
}
[...]
public class ImageAdapter extends BaseAdapter {
[...]
int itemBackground;
public ImageAdapter(Context c) {
context = c;
//---setting the style---
TypedArray a = obtainStyledAttributes(
R.styleable.Gallery1);
itemBackground = a.getResourceId(
R.styleable.Gallery1_android_galleryItemBackground, 0);
a.recycle();
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
[...]
imageView.setBackgroundResource(itemBackground);
return imageView;
}
}
}
I've read the code a few times and I don't really understand the purpose of defining this styleable Gallery1 with a single attr child only with a name attribute.. can you help me? Is this galleryItemBackground something provided by the system or is it something defined by us? What are we doing in this piece of code?
Thank you in advance for any help!
This tag is part of a set of premade Android attributes defined in R.Styleable
, which can be told apart from a custom styleable tag from the android:
xml namespace prefix before the attribute name.
This particular attribute is described as:
The preferred background for gallery items. This should be set as the background of any Views you provide from the Adapter.
You are right, however, that custom attribute tags would require not only the name of the attribute but what its type is, for example adding a custom element to your attrs.xml
file might look like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyCustomView">
<attr name=”android:galleryItemBackground” />
<attr name="myCustomAttr" format="string" />
</declare-styleable>
</resources>
Note the lack of the android:
namespace on the second attribute as well.
Edit:
Is there any official documentation page that explains in depth this Styleables?
Check out R.attr
(click for link) for various attributes included in Android. You do not need to declare a type for them, because they are all already declared. To know what type has been declared for a particular attribute, find the description for the one you are interested in. galleryItemBackground
is, as you may expect, a reference to another resource; other possibilities are booleans, floats, colors, etc.
Additional references: Andtoid uses the <declare-styleable>
tag to create an AttributeSet
. TypedArray
is used to parse the AttributeSet
.
If the purpose of the code above [...] is simply get a default Drawable for the view's background, couldn't I set the variable itemBackground with getDrawable(android.R.attr.galleryItemBackground)?
In the example, it is hard to see the usefulness of this pattern when there is only one attribute. You can do what you ask, and it may be easier. The construct, however, is part of Android's mantra to separate the UI's "look" from its "functionaly" by letting you set certain attributes in xml instead of having to do everything in code. Take the View
class, for example. It has over 30 attributes that can be set in an xml file (size, padding, clickable, focusable, etc); someone making a custom subclass of View
can set a few, all or none of these attributes in xml and they are automatically handled for you when the view is created. There are code equivalents to set the attributes if needed, but imagine every time you subclassed View
you HAD to set all attributes in code instead of having an option to set them in xml.
It would also be a trivial matter to just make your own resources for your classes that do exactly the same thing, however using the built in styles will provide default resources that match the look and feel of the Android framework if you do not override them.
Hope this helps.