I came across code at
ImageAdapter.java - http://developer.android.com/resources/tutorials/views/hello-gallery.html
TypedArray a = obtainStyledAttributes(R.styleable.HelloGallery); mGalleryItemBackground = a.getResourceId( R.styleable.HelloGallery_android_galleryItemBackground, 0); a.recycle();
attrs.xml - http://developer.android.com/resources/tutorials/views/hello-gallery.html
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="HelloGallery"> <attr name="android:galleryItemBackground" /> </declare-styleable> </resources>
and also code at :
TileView.java - http://developer.android.com/resources/samples/Snake/src/com/example/android/snake/TileView.html
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TileView); mTileSize = a.getInt(R.styleable.TileView_tileSize, 12); a.recycle();
attrs.html - http://developer.android.com/resources/samples/Snake/res/values/attrs.html
<resources> <declare-styleable name="TileView"> <attr name="tileSize" format="integer" /> </declare-styleable> </resources>
mGalleryItemBackground = 0;
and mTileSize = 12;
? My guess is that, they want to able to change something without touching Java code. But, I do not see any value being specified explicitly in the XML file itself. A code example to demonstrate the purpose of TypedArray and context.obtainStyledAttributes is very much appreicated. getResourceId
technique, another is using getInt
technique?recycle
does?Give back a previously retrieved StyledAttributes, for later re-use.
Container for an array of values that were retrieved with Resources. Theme#obtainStyledAttributes(AttributeSet, int[], int, int) or Resources#obtainAttributes .
1.1. fun <T> Collection<T>. toTypedArray(): Array<T> Returns a typed array containing all of the elements of this collection. Allocates an array of runtime type T having its size equal to the size of this collection and populates the array with the elements of this collection.
The recycle() causes the allocated memory to be returned to the available pool immediately and will not stay until garbage collection. This method is also available for Bitmap .
Note: A dimension is a simple resource that is referenced using the value provided in the name attribute (not the name of the XML file). As such, you can combine dimension resources with other simple resources in the one XML file, under one <resources> element. The filename is arbitrary.
- May I know why they need to get the integer value from XML? Why don't they just code mGalleryItemBackground = 0; and mTileSize = 12;?
I think it's mainly to demonstrate the technique of reading XML attributes from the View constructor, rather than to meet an absolute requirement. If you wanted to re-use your custom view elsewhere (not terribly likely for something as specific as Snake I'll admit) then this is a fantastically useful thing to be able to do... to change the backgound colour etc without having to touch the Java code.
For the tile size in particular, that might be useful to read from XML in case there are different layouts for different device types... you might want different size tiles for different density+size combinations.
- Both are trying to read an integer. Why one of the example is using getResourceId technique, another is using getInt technique?
Because the gallery background isn't an integer... it's expected to be a resource identifier (such as @drawable/foo). Yes it is still an integer, but an integer whose value isn't known until runtime. The tile size, by contrast, is a constant value and doesn't require any kind of runtime resolving.
- I refer to TypedArray JavaDoc, but I can hardly understand what recycle does?
If in doubt, look at the source. It's basically an optimization to avoid the LayoutInflater having to allocate one of these for every view it inflates.
In addition to being able to change that value without touching Java code, it allows them to apply different styles to their app depending on device configuration. Instead of declaring in XML:
<com.example.android.snake.SnakeView android:id="@+id/snake" android:layout_width="match_parent" android:layout_height="match_parent" tileSize="24" />
they can declare these values in res/values/styles.xml
:
<style name="Control.SnakeViewStyle"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">match_parent</item> <item name="tileSize">24</item> </style>
and then refer to that style:
<com.example.android.snake.SnakeView android:id="@+id/snake" style="@styles/SnakeViewStyle" />
After separating styles like this they can provide different styles.xml
file for each device configuration. For example, there might be one res/values/styles.xml
for portrait mode and one res/values-land/styles.xml
for landscape mode.
If a styleable attribute is declared as "reference" instead of "integer", you would (1) get IDE content assist when writing XML for that attribute and (2) compiler would check that you haven't provided a reference to non-existing resource. Consequently, to get it you need to use getResourceId
, because it may do some additional resolving to get actual resource id.
I'm not really sure, but judging by the code of TypedArray
, it seems that there's some caching mechanism inside it, and recycle()
makes it work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With