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