• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package android.content.res;
2 
3 import android.graphics.drawable.Drawable;
4 import android.util.AttributeSet;
5 import android.util.DisplayMetrics;
6 import android.util.Log;
7 import android.util.TypedValue;
8 import com.android.internal.util.XmlUtils;
9 
10 import 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  */
21 public 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      */
length()33     public int length() {
34         return mLength;
35     }
36 
37     /**
38      * Return the number of indices in the array that actually have data.
39      */
getIndexCount()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      */
getIndex(int at)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      */
getResources()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      */
getText(int index)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      */
getString(int index)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      */
getNonResourceString(int index)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      */
getBoolean(int index, boolean defValue)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      */
getInt(int index, int defValue)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      */
getFloat(int index, float defValue)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      */
getColor(int index, int defValue)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      */
getColorStateList(int index)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      */
getInteger(int index, int defValue)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      */
getDimension(int index, float defValue)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      */
getDimensionPixelOffset(int index, int defValue)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      */
getDimensionPixelSize(int index, int defValue)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      */
getLayoutDimension(int index, String name)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      */
getLayoutDimension(int index, int defValue)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      */
getFraction(int index, int base, int pbase, float defValue)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      */
getResourceId(int index, int defValue)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      */
getDrawable(int index)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      */
getTextArray(int index)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      */
getValue(int index, TypedValue outValue)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      */
hasValue(int index)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      */
peekValue(int index)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      */
getPositionDescription()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      */
recycle()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 
getValueAt(int index, TypedValue outValue)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];
657         outValue.density = data[index+AssetManager.STYLE_DENSITY];
658         if (type == TypedValue.TYPE_STRING) {
659             outValue.string = loadStringValueAt(index);
660         }
661         return true;
662     }
663 
loadStringValueAt(int index)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 
TypedArray(Resources resources, int[] data, int[] indices, int len)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 
toString()686     public String toString() {
687         return Arrays.toString(mData);
688     }
689 }