blob: 8f0003b71db87d766404d840d9863210347a1906 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001package android.content.res;
2
3import android.graphics.drawable.Drawable;
4import android.util.AttributeSet;
5import android.util.DisplayMetrics;
6import android.util.Log;
7import android.util.TypedValue;
Tom Taylord4a47292009-12-21 13:59:18 -08008import com.android.common.XmlUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009
10import java.util.Arrays;
11
12/**
13 * Container for an array of values that were retrieved with
14 * {@link Resources.Theme#obtainStyledAttributes(AttributeSet, int[], int, int)}
15 * or {@link Resources#obtainAttributes}. Be
16 * sure to call {@link #recycle} when done with them.
17 *
18 * The indices used to retrieve values from this structure correspond to
19 * the positions of the attributes given to obtainStyledAttributes.
20 */
21public class TypedArray {
22 private final Resources mResources;
23 /*package*/ XmlBlock.Parser mXml;
24 /*package*/ int[] mRsrcs;
25 /*package*/ int[] mData;
26 /*package*/ int[] mIndices;
27 /*package*/ int mLength;
28 private TypedValue mValue = new TypedValue();
29
30 /**
31 * Return the number of values in this array.
32 */
33 public int length() {
34 return mLength;
35 }
36
37 /**
38 * Return the number of indices in the array that actually have data.
39 */
40 public int getIndexCount() {
41 return mIndices[0];
42 }
43
44 /**
45 * Return an index in the array that has data.
46 *
47 * @param at The index you would like to returned, ranging from 0 to
48 * {@link #getIndexCount()}.
49 *
50 * @return The index at the given offset, which can be used with
51 * {@link #getValue} and related APIs.
52 */
53 public int getIndex(int at) {
54 return mIndices[1+at];
55 }
56
57 /**
58 * Return the Resources object this array was loaded from.
59 */
60 public Resources getResources() {
61 return mResources;
62 }
63
64 /**
65 * Retrieve the styled string value for the attribute at <var>index</var>.
66 *
67 * @param index Index of attribute to retrieve.
68 *
69 * @return CharSequence holding string data. May be styled. Returns
70 * null if the attribute is not defined.
71 */
72 public CharSequence getText(int index) {
73 index *= AssetManager.STYLE_NUM_ENTRIES;
74 final int[] data = mData;
75 final int type = data[index+AssetManager.STYLE_TYPE];
76 if (type == TypedValue.TYPE_NULL) {
77 return null;
78 } else if (type == TypedValue.TYPE_STRING) {
79 return loadStringValueAt(index);
80 }
81
82 TypedValue v = mValue;
83 if (getValueAt(index, v)) {
84 Log.w(Resources.TAG, "Converting to string: " + v);
85 return v.coerceToString();
86 }
87 Log.w(Resources.TAG, "getString of bad type: 0x"
88 + Integer.toHexString(type));
89 return null;
90 }
91
92 /**
93 * Retrieve the string value for the attribute at <var>index</var>.
94 *
95 * @param index Index of attribute to retrieve.
96 *
97 * @return String holding string data. Any styling information is
98 * removed. Returns null if the attribute is not defined.
99 */
100 public String getString(int index) {
101 index *= AssetManager.STYLE_NUM_ENTRIES;
102 final int[] data = mData;
103 final int type = data[index+AssetManager.STYLE_TYPE];
104 if (type == TypedValue.TYPE_NULL) {
105 return null;
106 } else if (type == TypedValue.TYPE_STRING) {
107 return loadStringValueAt(index).toString();
108 }
109
110 TypedValue v = mValue;
111 if (getValueAt(index, v)) {
112 Log.w(Resources.TAG, "Converting to string: " + v);
113 CharSequence cs = v.coerceToString();
114 return cs != null ? cs.toString() : null;
115 }
116 Log.w(Resources.TAG, "getString of bad type: 0x"
117 + Integer.toHexString(type));
118 return null;
119 }
120
121 /**
122 * Retrieve the string value for the attribute at <var>index</var>, but
123 * only if that string comes from an immediate value in an XML file. That
124 * is, this does not allow references to string resources, string
125 * attributes, or conversions from other types. As such, this method
126 * will only return strings for TypedArray objects that come from
127 * attributes in an XML file.
128 *
129 * @param index Index of attribute to retrieve.
130 *
131 * @return String holding string data. Any styling information is
132 * removed. Returns null if the attribute is not defined or is not
133 * an immediate string value.
134 */
135 public String getNonResourceString(int index) {
136 index *= AssetManager.STYLE_NUM_ENTRIES;
137 final int[] data = mData;
138 final int type = data[index+AssetManager.STYLE_TYPE];
139 if (type == TypedValue.TYPE_STRING) {
140 final int cookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
141 if (cookie < 0) {
142 return mXml.getPooledString(
143 data[index+AssetManager.STYLE_DATA]).toString();
144 }
145 }
146 return null;
147 }
148
149 /**
150 * Retrieve the boolean value for the attribute at <var>index</var>.
151 *
152 * @param index Index of attribute to retrieve.
153 * @param defValue Value to return if the attribute is not defined.
154 *
155 * @return Attribute boolean value, or defValue if not defined.
156 */
157 public boolean getBoolean(int index, boolean defValue) {
158 index *= AssetManager.STYLE_NUM_ENTRIES;
159 final int[] data = mData;
160 final int type = data[index+AssetManager.STYLE_TYPE];
161 if (type == TypedValue.TYPE_NULL) {
162 return defValue;
163 } else if (type >= TypedValue.TYPE_FIRST_INT
164 && type <= TypedValue.TYPE_LAST_INT) {
165 return data[index+AssetManager.STYLE_DATA] != 0;
166 }
167
168 TypedValue v = mValue;
169 if (getValueAt(index, v)) {
170 Log.w(Resources.TAG, "Converting to boolean: " + v);
171 return XmlUtils.convertValueToBoolean(
172 v.coerceToString(), defValue);
173 }
174 Log.w(Resources.TAG, "getBoolean of bad type: 0x"
175 + Integer.toHexString(type));
176 return defValue;
177 }
178
179 /**
180 * Retrieve the integer value for the attribute at <var>index</var>.
181 *
182 * @param index Index of attribute to retrieve.
183 * @param defValue Value to return if the attribute is not defined.
184 *
185 * @return Attribute int value, or defValue if not defined.
186 */
187 public int getInt(int index, int defValue) {
188 index *= AssetManager.STYLE_NUM_ENTRIES;
189 final int[] data = mData;
190 final int type = data[index+AssetManager.STYLE_TYPE];
191 if (type == TypedValue.TYPE_NULL) {
192 return defValue;
193 } else if (type >= TypedValue.TYPE_FIRST_INT
194 && type <= TypedValue.TYPE_LAST_INT) {
195 return data[index+AssetManager.STYLE_DATA];
196 }
197
198 TypedValue v = mValue;
199 if (getValueAt(index, v)) {
200 Log.w(Resources.TAG, "Converting to int: " + v);
201 return XmlUtils.convertValueToInt(
202 v.coerceToString(), defValue);
203 }
204 Log.w(Resources.TAG, "getInt of bad type: 0x"
205 + Integer.toHexString(type));
206 return defValue;
207 }
208
209 /**
210 * Retrieve the float value for the attribute at <var>index</var>.
211 *
212 * @param index Index of attribute to retrieve.
213 *
214 * @return Attribute float value, or defValue if not defined..
215 */
216 public float getFloat(int index, float defValue) {
217 index *= AssetManager.STYLE_NUM_ENTRIES;
218 final int[] data = mData;
219 final int type = data[index+AssetManager.STYLE_TYPE];
220 if (type == TypedValue.TYPE_NULL) {
221 return defValue;
222 } else if (type == TypedValue.TYPE_FLOAT) {
223 return Float.intBitsToFloat(data[index+AssetManager.STYLE_DATA]);
224 } else if (type >= TypedValue.TYPE_FIRST_INT
225 && type <= TypedValue.TYPE_LAST_INT) {
226 return data[index+AssetManager.STYLE_DATA];
227 }
228
229 TypedValue v = mValue;
230 if (getValueAt(index, v)) {
231 Log.w(Resources.TAG, "Converting to float: " + v);
232 CharSequence str = v.coerceToString();
233 if (str != null) {
234 return Float.parseFloat(str.toString());
235 }
236 }
237 Log.w(Resources.TAG, "getFloat of bad type: 0x"
238 + Integer.toHexString(type));
239 return defValue;
240 }
241
242 /**
243 * Retrieve the color value for the attribute at <var>index</var>. If
244 * the attribute references a color resource holding a complex
245 * {@link android.content.res.ColorStateList}, then the default color from
246 * the set is returned.
247 *
248 * @param index Index of attribute to retrieve.
249 * @param defValue Value to return if the attribute is not defined or
250 * not a resource.
251 *
252 * @return Attribute color value, or defValue if not defined.
253 */
254 public int getColor(int index, int defValue) {
255 index *= AssetManager.STYLE_NUM_ENTRIES;
256 final int[] data = mData;
257 final int type = data[index+AssetManager.STYLE_TYPE];
258 if (type == TypedValue.TYPE_NULL) {
259 return defValue;
260 } else if (type >= TypedValue.TYPE_FIRST_INT
261 && type <= TypedValue.TYPE_LAST_INT) {
262 return data[index+AssetManager.STYLE_DATA];
263 } else if (type == TypedValue.TYPE_STRING) {
264 final TypedValue value = mValue;
265 if (getValueAt(index, value)) {
266 ColorStateList csl = mResources.loadColorStateList(
267 value, value.resourceId);
268 return csl.getDefaultColor();
269 }
270 return defValue;
271 }
272
273 throw new UnsupportedOperationException("Can't convert to color: type=0x"
274 + Integer.toHexString(type));
275 }
276
277 /**
278 * Retrieve the ColorStateList for the attribute at <var>index</var>.
279 * The value may be either a single solid color or a reference to
280 * a color or complex {@link android.content.res.ColorStateList} description.
281 *
282 * @param index Index of attribute to retrieve.
283 *
284 * @return ColorStateList for the attribute, or null if not defined.
285 */
286 public ColorStateList getColorStateList(int index) {
287 final TypedValue value = mValue;
288 if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
289 return mResources.loadColorStateList(value, value.resourceId);
290 }
291 return null;
292 }
293
294 /**
295 * Retrieve the integer value for the attribute at <var>index</var>.
296 *
297 * @param index Index of attribute to retrieve.
298 * @param defValue Value to return if the attribute is not defined or
299 * not a resource.
300 *
301 * @return Attribute integer value, or defValue if not defined.
302 */
303 public int getInteger(int index, int defValue) {
304 index *= AssetManager.STYLE_NUM_ENTRIES;
305 final int[] data = mData;
306 final int type = data[index+AssetManager.STYLE_TYPE];
307 if (type == TypedValue.TYPE_NULL) {
308 return defValue;
309 } else if (type >= TypedValue.TYPE_FIRST_INT
310 && type <= TypedValue.TYPE_LAST_INT) {
311 return data[index+AssetManager.STYLE_DATA];
312 }
313
314 throw new UnsupportedOperationException("Can't convert to integer: type=0x"
315 + Integer.toHexString(type));
316 }
317
318 /**
319 * Retrieve a dimensional unit attribute at <var>index</var>. Unit
320 * conversions are based on the current {@link DisplayMetrics}
321 * associated with the resources this {@link TypedArray} object
322 * came from.
323 *
324 * @param index Index of attribute to retrieve.
325 * @param defValue Value to return if the attribute is not defined or
326 * not a resource.
327 *
328 * @return Attribute dimension value multiplied by the appropriate
329 * metric, or defValue if not defined.
330 *
331 * @see #getDimensionPixelOffset
332 * @see #getDimensionPixelSize
333 */
334 public float getDimension(int index, float defValue) {
335 index *= AssetManager.STYLE_NUM_ENTRIES;
336 final int[] data = mData;
337 final int type = data[index+AssetManager.STYLE_TYPE];
338 if (type == TypedValue.TYPE_NULL) {
339 return defValue;
340 } else if (type == TypedValue.TYPE_DIMENSION) {
341 return TypedValue.complexToDimension(
342 data[index+AssetManager.STYLE_DATA], mResources.mMetrics);
343 }
344
345 throw new UnsupportedOperationException("Can't convert to dimension: type=0x"
346 + Integer.toHexString(type));
347 }
348
349 /**
350 * Retrieve a dimensional unit attribute at <var>index</var> for use
351 * as an offset in raw pixels. This is the same as
352 * {@link #getDimension}, except the returned value is converted to
353 * integer pixels for you. An offset conversion involves simply
354 * truncating the base value to an integer.
355 *
356 * @param index Index of attribute to retrieve.
357 * @param defValue Value to return if the attribute is not defined or
358 * not a resource.
359 *
360 * @return Attribute dimension value multiplied by the appropriate
361 * metric and truncated to integer pixels, or defValue if not defined.
362 *
363 * @see #getDimension
364 * @see #getDimensionPixelSize
365 */
366 public int getDimensionPixelOffset(int index, int defValue) {
367 index *= AssetManager.STYLE_NUM_ENTRIES;
368 final int[] data = mData;
369 final int type = data[index+AssetManager.STYLE_TYPE];
370 if (type == TypedValue.TYPE_NULL) {
371 return defValue;
372 } else if (type == TypedValue.TYPE_DIMENSION) {
373 return TypedValue.complexToDimensionPixelOffset(
374 data[index+AssetManager.STYLE_DATA], mResources.mMetrics);
375 }
376
377 throw new UnsupportedOperationException("Can't convert to dimension: type=0x"
378 + Integer.toHexString(type));
379 }
380
381 /**
382 * Retrieve a dimensional unit attribute at <var>index</var> for use
383 * as a size in raw pixels. This is the same as
384 * {@link #getDimension}, except the returned value is converted to
385 * integer pixels for use as a size. A size conversion involves
386 * rounding the base value, and ensuring that a non-zero base value
387 * is at least one pixel in size.
388 *
389 * @param index Index of attribute to retrieve.
390 * @param defValue Value to return if the attribute is not defined or
391 * not a resource.
392 *
393 * @return Attribute dimension value multiplied by the appropriate
394 * metric and truncated to integer pixels, or defValue if not defined.
395 *
396 * @see #getDimension
397 * @see #getDimensionPixelOffset
398 */
399 public int getDimensionPixelSize(int index, int defValue) {
400 index *= AssetManager.STYLE_NUM_ENTRIES;
401 final int[] data = mData;
402 final int type = data[index+AssetManager.STYLE_TYPE];
403 if (type == TypedValue.TYPE_NULL) {
404 return defValue;
405 } else if (type == TypedValue.TYPE_DIMENSION) {
406 return TypedValue.complexToDimensionPixelSize(
407 data[index+AssetManager.STYLE_DATA], mResources.mMetrics);
408 }
409
410 throw new UnsupportedOperationException("Can't convert to dimension: type=0x"
411 + Integer.toHexString(type));
412 }
413
414 /**
415 * Special version of {@link #getDimensionPixelSize} for retrieving
416 * {@link android.view.ViewGroup}'s layout_width and layout_height
417 * attributes. This is only here for performance reasons; applications
418 * should use {@link #getDimensionPixelSize}.
419 *
420 * @param index Index of the attribute to retrieve.
421 * @param name Textual name of attribute for error reporting.
422 *
423 * @return Attribute dimension value multiplied by the appropriate
424 * metric and truncated to integer pixels.
425 */
426 public int getLayoutDimension(int index, String name) {
427 index *= AssetManager.STYLE_NUM_ENTRIES;
428 final int[] data = mData;
429 final int type = data[index+AssetManager.STYLE_TYPE];
430 if (type >= TypedValue.TYPE_FIRST_INT
431 && type <= TypedValue.TYPE_LAST_INT) {
432 return data[index+AssetManager.STYLE_DATA];
433 } else if (type == TypedValue.TYPE_DIMENSION) {
434 return TypedValue.complexToDimensionPixelSize(
435 data[index+AssetManager.STYLE_DATA], mResources.mMetrics);
436 }
437
438 throw new RuntimeException(getPositionDescription()
439 + ": You must supply a " + name + " attribute.");
440 }
441
442 /**
443 * Special version of {@link #getDimensionPixelSize} for retrieving
444 * {@link android.view.ViewGroup}'s layout_width and layout_height
445 * attributes. This is only here for performance reasons; applications
446 * should use {@link #getDimensionPixelSize}.
447 *
448 * @param index Index of the attribute to retrieve.
449 * @param defValue The default value to return if this attribute is not
450 * default or contains the wrong type of data.
451 *
452 * @return Attribute dimension value multiplied by the appropriate
453 * metric and truncated to integer pixels.
454 */
455 public int getLayoutDimension(int index, int defValue) {
456 index *= AssetManager.STYLE_NUM_ENTRIES;
457 final int[] data = mData;
458 final int type = data[index+AssetManager.STYLE_TYPE];
459 if (type >= TypedValue.TYPE_FIRST_INT
460 && type <= TypedValue.TYPE_LAST_INT) {
461 return data[index+AssetManager.STYLE_DATA];
462 } else if (type == TypedValue.TYPE_DIMENSION) {
463 return TypedValue.complexToDimensionPixelSize(
464 data[index+AssetManager.STYLE_DATA], mResources.mMetrics);
465 }
466
467 return defValue;
468 }
469
470 /**
471 * Retrieve a fractional unit attribute at <var>index</var>.
472 *
473 * @param index Index of attribute to retrieve.
474 * @param base The base value of this fraction. In other words, a
475 * standard fraction is multiplied by this value.
476 * @param pbase The parent base value of this fraction. In other
477 * words, a parent fraction (nn%p) is multiplied by this
478 * value.
479 * @param defValue Value to return if the attribute is not defined or
480 * not a resource.
481 *
482 * @return Attribute fractional value multiplied by the appropriate
483 * base value, or defValue if not defined.
484 */
485 public float getFraction(int index, int base, int pbase, float defValue) {
486 index *= AssetManager.STYLE_NUM_ENTRIES;
487 final int[] data = mData;
488 final int type = data[index+AssetManager.STYLE_TYPE];
489 if (type == TypedValue.TYPE_NULL) {
490 return defValue;
491 } else if (type == TypedValue.TYPE_FRACTION) {
492 return TypedValue.complexToFraction(
493 data[index+AssetManager.STYLE_DATA], base, pbase);
494 }
495
496 throw new UnsupportedOperationException("Can't convert to fraction: type=0x"
497 + Integer.toHexString(type));
498 }
499
500 /**
501 * Retrieve the resource identifier for the attribute at
502 * <var>index</var>. Note that attribute resource as resolved when
503 * the overall {@link TypedArray} object is retrieved. As a
504 * result, this function will return the resource identifier of the
505 * final resource value that was found, <em>not</em> necessarily the
506 * original resource that was specified by the attribute.
507 *
508 * @param index Index of attribute to retrieve.
509 * @param defValue Value to return if the attribute is not defined or
510 * not a resource.
511 *
512 * @return Attribute resource identifier, or defValue if not defined.
513 */
514 public int getResourceId(int index, int defValue) {
515 index *= AssetManager.STYLE_NUM_ENTRIES;
516 final int[] data = mData;
517 if (data[index+AssetManager.STYLE_TYPE] != TypedValue.TYPE_NULL) {
518 final int resid = data[index+AssetManager.STYLE_RESOURCE_ID];
519 if (resid != 0) {
520 return resid;
521 }
522 }
523 return defValue;
524 }
525
526 /**
527 * Retrieve the Drawable for the attribute at <var>index</var>. This
528 * gets the resource ID of the selected attribute, and uses
529 * {@link Resources#getDrawable Resources.getDrawable} of the owning
530 * Resources object to retrieve its Drawable.
531 *
532 * @param index Index of attribute to retrieve.
533 *
534 * @return Drawable for the attribute, or null if not defined.
535 */
536 public Drawable getDrawable(int index) {
537 final TypedValue value = mValue;
538 if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
539 if (false) {
540 System.out.println("******************************************************************");
541 System.out.println("Got drawable resource: type="
542 + value.type
543 + " str=" + value.string
544 + " int=0x" + Integer.toHexString(value.data)
545 + " cookie=" + value.assetCookie);
546 System.out.println("******************************************************************");
547 }
548 return mResources.loadDrawable(value, value.resourceId);
549 }
550 return null;
551 }
552
553 /**
554 * Retrieve the CharSequence[] for the attribute at <var>index</var>.
555 * This gets the resource ID of the selected attribute, and uses
556 * {@link Resources#getTextArray Resources.getTextArray} of the owning
557 * Resources object to retrieve its String[].
558 *
559 * @param index Index of attribute to retrieve.
560 *
561 * @return CharSequence[] for the attribute, or null if not defined.
562 */
563 public CharSequence[] getTextArray(int index) {
564 final TypedValue value = mValue;
565 if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
566 if (false) {
567 System.out.println("******************************************************************");
568 System.out.println("Got drawable resource: type="
569 + value.type
570 + " str=" + value.string
571 + " int=0x" + Integer.toHexString(value.data)
572 + " cookie=" + value.assetCookie);
573 System.out.println("******************************************************************");
574 }
575 return mResources.getTextArray(value.resourceId);
576 }
577 return null;
578 }
579
580 /**
581 * Retrieve the raw TypedValue for the attribute at <var>index</var>.
582 *
583 * @param index Index of attribute to retrieve.
584 * @param outValue TypedValue object in which to place the attribute's
585 * data.
586 *
587 * @return Returns true if the value was retrieved, else false.
588 */
589 public boolean getValue(int index, TypedValue outValue) {
590 return getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, outValue);
591 }
592
593 /**
594 * Determines whether there is an attribute at <var>index</var>.
595 *
596 * @param index Index of attribute to retrieve.
597 *
598 * @return True if the attribute has a value, false otherwise.
599 */
600 public boolean hasValue(int index) {
601 index *= AssetManager.STYLE_NUM_ENTRIES;
602 final int[] data = mData;
603 final int type = data[index+AssetManager.STYLE_TYPE];
604 return type != TypedValue.TYPE_NULL;
605 }
606
607 /**
608 * Retrieve the raw TypedValue for the attribute at <var>index</var>
609 * and return a temporary object holding its data. This object is only
610 * valid until the next call on to {@link TypedArray}.
611 *
612 * @param index Index of attribute to retrieve.
613 *
614 * @return Returns a TypedValue object if the attribute is defined,
615 * containing its data; otherwise returns null. (You will not
616 * receive a TypedValue whose type is TYPE_NULL.)
617 */
618 public TypedValue peekValue(int index) {
619 final TypedValue value = mValue;
620 if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
621 return value;
622 }
623 return null;
624 }
625
626 /**
627 * Returns a message about the parser state suitable for printing error messages.
628 */
629 public String getPositionDescription() {
630 return mXml != null ? mXml.getPositionDescription() : "<internal>";
631 }
632
633 /**
634 * Give back a previously retrieved StyledAttributes, for later re-use.
635 */
636 public void recycle() {
637 synchronized (mResources.mTmpValue) {
638 TypedArray cached = mResources.mCachedStyledAttributes;
639 if (cached == null || cached.mData.length < mData.length) {
640 mXml = null;
641 mResources.mCachedStyledAttributes = this;
642 }
643 }
644 }
645
646 private boolean getValueAt(int index, TypedValue outValue) {
647 final int[] data = mData;
648 final int type = data[index+AssetManager.STYLE_TYPE];
649 if (type == TypedValue.TYPE_NULL) {
650 return false;
651 }
652 outValue.type = type;
653 outValue.data = data[index+AssetManager.STYLE_DATA];
654 outValue.assetCookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
655 outValue.resourceId = data[index+AssetManager.STYLE_RESOURCE_ID];
656 outValue.changingConfigurations = data[index+AssetManager.STYLE_CHANGING_CONFIGURATIONS];
Dianne Hackborn0d221012009-07-29 15:41:19 -0700657 outValue.density = data[index+AssetManager.STYLE_DENSITY];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800658 if (type == TypedValue.TYPE_STRING) {
659 outValue.string = loadStringValueAt(index);
660 }
661 return true;
662 }
663
664 private CharSequence loadStringValueAt(int index) {
665 final int[] data = mData;
666 final int cookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
667 if (cookie < 0) {
668 if (mXml != null) {
669 return mXml.getPooledString(
670 data[index+AssetManager.STYLE_DATA]);
671 }
672 return null;
673 }
674 //System.out.println("Getting pooled from: " + v);
675 return mResources.mAssets.getPooledString(
676 cookie, data[index+AssetManager.STYLE_DATA]);
677 }
678
679 /*package*/ TypedArray(Resources resources, int[] data, int[] indices, int len) {
680 mResources = resources;
681 mData = data;
682 mIndices = indices;
683 mLength = len;
684 }
685
686 public String toString() {
687 return Arrays.toString(mData);
688 }
689}