blob: b79cf6566987729e55c46c4154d181fc8d4b3558 [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
Tor Norbye7b9c9122013-05-30 16:48:33 -070019import android.annotation.AnyRes;
Tor Norbye80756e32015-03-02 09:39:27 -080020import android.annotation.ColorInt;
Alan Viverettefde4e3b2014-09-22 16:19:51 -070021import android.annotation.Nullable;
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -070022import android.annotation.StyleableRes;
Mathew Inwood5c0d3542018-08-14 13:54:31 +010023import android.annotation.UnsupportedAppUsage;
Alan Viveretteac85f902016-03-11 15:15:51 -050024import android.content.pm.ActivityInfo;
25import android.content.pm.ActivityInfo.Config;
Clara Bayarried00bfd2017-01-20 14:58:21 +000026import android.graphics.Typeface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import android.graphics.drawable.Drawable;
Alan Viverette6bbb47b2015-01-05 18:12:44 -080028import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.util.AttributeSet;
30import android.util.DisplayMetrics;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.util.TypedValue;
Dianne Hackborn2269d1572010-02-24 19:54:22 -080032
33import com.android.internal.util.XmlUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034
John Reckf32adf42016-11-23 10:39:40 -080035import dalvik.system.VMRuntime;
36
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import java.util.Arrays;
38
39/**
40 * Container for an array of values that were retrieved with
41 * {@link Resources.Theme#obtainStyledAttributes(AttributeSet, int[], int, int)}
42 * or {@link Resources#obtainAttributes}. Be
43 * sure to call {@link #recycle} when done with them.
Alan Viverettefd274a02014-03-27 15:39:15 -070044 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045 * The indices used to retrieve values from this structure correspond to
46 * the positions of the attributes given to obtainStyledAttributes.
47 */
48public class TypedArray {
Alan Viverette52b999f2014-03-24 18:00:26 -070049
50 static TypedArray obtain(Resources res, int len) {
John Reckf32adf42016-11-23 10:39:40 -080051 TypedArray attrs = res.mTypedArrayPool.acquire();
52 if (attrs == null) {
53 attrs = new TypedArray(res);
Alan Viverette52b999f2014-03-24 18:00:26 -070054 }
55
John Reckf32adf42016-11-23 10:39:40 -080056 attrs.mRecycled = false;
57 // Reset the assets, which may have changed due to configuration changes
58 // or further resource loading.
59 attrs.mAssets = res.getAssets();
Adam Lesinskiec05bc02017-04-18 14:42:22 -070060 attrs.mMetrics = res.getDisplayMetrics();
John Reckf32adf42016-11-23 10:39:40 -080061 attrs.resize(len);
62 return attrs;
Alan Viverette52b999f2014-03-24 18:00:26 -070063 }
64
Adam Lesinskibebfcc42018-02-12 14:27:46 -080065 // STYLE_ prefixed constants are offsets within the typed data array.
Aurimas Liutikasce7c99c2018-12-18 16:20:49 -080066 // Keep this in sync with libs/androidfw/include/androidfw/AttributeResolution.h
67 static final int STYLE_NUM_ENTRIES = 7;
Adam Lesinskibebfcc42018-02-12 14:27:46 -080068 static final int STYLE_TYPE = 0;
69 static final int STYLE_DATA = 1;
70 static final int STYLE_ASSET_COOKIE = 2;
71 static final int STYLE_RESOURCE_ID = 3;
72 static final int STYLE_CHANGING_CONFIGURATIONS = 4;
73 static final int STYLE_DENSITY = 5;
Aurimas Liutikasf9dbd5f2019-03-07 11:21:51 -080074 static final int STYLE_SOURCE_RESOURCE_ID = 6;
Adam Lesinskibebfcc42018-02-12 14:27:46 -080075
Mathew Inwood5c0d3542018-08-14 13:54:31 +010076 @UnsupportedAppUsage
Alan Viverette8b5b25b2014-09-13 19:30:11 -070077 private final Resources mResources;
Mathew Inwood5c0d3542018-08-14 13:54:31 +010078 @UnsupportedAppUsage
Adam Lesinskiec05bc02017-04-18 14:42:22 -070079 private DisplayMetrics mMetrics;
Mathew Inwood5c0d3542018-08-14 13:54:31 +010080 @UnsupportedAppUsage
Adam Lesinskie60064a2016-07-13 12:09:24 -070081 private AssetManager mAssets;
Alan Viverette8b5b25b2014-09-13 19:30:11 -070082
Mathew Inwood5c0d3542018-08-14 13:54:31 +010083 @UnsupportedAppUsage
Alan Viverettefd274a02014-03-27 15:39:15 -070084 private boolean mRecycled;
85
Mathew Inwood5c0d3542018-08-14 13:54:31 +010086 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087 /*package*/ XmlBlock.Parser mXml;
Mathew Inwood5c0d3542018-08-14 13:54:31 +010088 @UnsupportedAppUsage
Alan Viverette52b999f2014-03-24 18:00:26 -070089 /*package*/ Resources.Theme mTheme;
Aurimas Liutikasbf1c1fc2018-08-27 15:38:36 -070090 /**
91 * mData is used to hold the value/id and other metadata about each attribute.
92 *
93 * [type, data, asset cookie, resource id, changing configuration, density]
94 *
95 * type - type of this attribute, see TypedValue#TYPE_*
96 *
97 * data - can be used in various ways:
98 * a) actual value of the attribute if type is between #TYPE_FIRST_INT and #TYPE_LAST_INT
99 * 1) color represented by an integer (#TYPE_INT_COLOR_*)
100 * 2) boolean represented by an integer (#TYPE_INT_BOOLEAN)
101 * 3) integer number (#TYPE_TYPE_INT_DEC or #TYPE_INT_HEX)
102 * 4) float number where integer gets interpreted as float (#TYPE_FLOAT, #TYPE_FRACTION
103 * and #TYPE_DIMENSION)
104 * b) index into string block inside AssetManager (#TYPE_STRING)
105 * c) attribute resource id in the current theme/style (#TYPE_ATTRIBUTE)
106 *
107 * asset cookie - used in two ways:
108 * a) for strings, drawables, and fonts it specifies the set of apk assets to look at
109 * (multi-apk case)
110 * b) cookie + asset as a unique identifier for drawable caches
111 *
112 * resource id - id that was finally used to resolve this attribute
113 *
114 * changing configuration - a mask of the configuration parameters for which the values in this
115 * attribute may change
116 *
117 * density - density of drawable pointed to by this attribute
118 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100119 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120 /*package*/ int[] mData;
Aurimas Liutikasbf1c1fc2018-08-27 15:38:36 -0700121 /**
122 * Pointer to the start of the memory address of mData. It is passed via JNI and used to write
123 * to mData array directly from native code (AttributeResolution.cpp).
124 */
John Reckf32adf42016-11-23 10:39:40 -0800125 /*package*/ long mDataAddress;
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100126 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127 /*package*/ int[] mIndices;
Aurimas Liutikasbf1c1fc2018-08-27 15:38:36 -0700128 /**
129 * Similar to mDataAddress, but instead it is a pointer to mIndices address.
130 */
John Reckf32adf42016-11-23 10:39:40 -0800131 /*package*/ long mIndicesAddress;
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100132 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133 /*package*/ int mLength;
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100134 @UnsupportedAppUsage
Xavier Ducrohet7f9f99ea2011-08-11 10:16:17 -0700135 /*package*/ TypedValue mValue = new TypedValue();
Alan Viverette8eea3ea2014-02-03 18:40:20 -0800136
John Reckf32adf42016-11-23 10:39:40 -0800137 private void resize(int len) {
138 mLength = len;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800139 final int dataLen = len * STYLE_NUM_ENTRIES;
John Reckf32adf42016-11-23 10:39:40 -0800140 final int indicesLen = len + 1;
141 final VMRuntime runtime = VMRuntime.getRuntime();
John Reckabd917d2017-01-04 19:04:25 -0800142 if (mDataAddress == 0 || mData.length < dataLen) {
John Reckf32adf42016-11-23 10:39:40 -0800143 mData = (int[]) runtime.newNonMovableArray(int.class, dataLen);
144 mDataAddress = runtime.addressOf(mData);
145 mIndices = (int[]) runtime.newNonMovableArray(int.class, indicesLen);
146 mIndicesAddress = runtime.addressOf(mIndices);
147 }
148 }
149
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800151 * Returns the number of values in this array.
152 *
153 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154 */
155 public int length() {
Alan Viverettefd274a02014-03-27 15:39:15 -0700156 if (mRecycled) {
157 throw new RuntimeException("Cannot make calls to a recycled instance!");
158 }
159
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 return mLength;
161 }
Alan Viverettefd274a02014-03-27 15:39:15 -0700162
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 /**
Adam Lesinski32e75012017-05-09 15:25:37 -0700164 * Returns the number of indices in the array that actually have data. Attributes with a value
165 * of @empty are included, as this is an explicit indicator.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800166 *
167 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 */
169 public int getIndexCount() {
Alan Viverettefd274a02014-03-27 15:39:15 -0700170 if (mRecycled) {
171 throw new RuntimeException("Cannot make calls to a recycled instance!");
172 }
173
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 return mIndices[0];
175 }
Alan Viverettefd274a02014-03-27 15:39:15 -0700176
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800177 /**
Adam Lesinski32e75012017-05-09 15:25:37 -0700178 * Returns an index in the array that has data. Attributes with a value of @empty are included,
179 * as this is an explicit indicator.
Alan Viverettefd274a02014-03-27 15:39:15 -0700180 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181 * @param at The index you would like to returned, ranging from 0 to
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800182 * {@link #getIndexCount()}.
Alan Viverettefd274a02014-03-27 15:39:15 -0700183 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184 * @return The index at the given offset, which can be used with
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800185 * {@link #getValue} and related APIs.
186 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 */
188 public int getIndex(int at) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700189 if (mRecycled) {
190 throw new RuntimeException("Cannot make calls to a recycled instance!");
191 }
192
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193 return mIndices[1+at];
194 }
Alan Viverettefd274a02014-03-27 15:39:15 -0700195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800197 * Returns the Resources object this array was loaded from.
198 *
199 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200 */
201 public Resources getResources() {
Alan Viverettefd274a02014-03-27 15:39:15 -0700202 if (mRecycled) {
203 throw new RuntimeException("Cannot make calls to a recycled instance!");
204 }
205
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 return mResources;
207 }
Alan Viverettefd274a02014-03-27 15:39:15 -0700208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800210 * Retrieves the styled string value for the attribute at <var>index</var>.
211 * <p>
212 * If the attribute is not a string, this method will attempt to coerce
213 * it to a string.
Alan Viverettefd274a02014-03-27 15:39:15 -0700214 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -0700216 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800217 * @return CharSequence holding string data. May be styled. Returns
218 * {@code null} if the attribute is not defined or could not be
219 * coerced to a string.
220 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700222 public CharSequence getText(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700223 if (mRecycled) {
224 throw new RuntimeException("Cannot make calls to a recycled instance!");
225 }
226
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800227 index *= STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800228 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800229 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800230 if (type == TypedValue.TYPE_NULL) {
231 return null;
232 } else if (type == TypedValue.TYPE_STRING) {
233 return loadStringValueAt(index);
234 }
235
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800236 final TypedValue v = mValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800237 if (getValueAt(index, v)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800238 return v.coerceToString();
239 }
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800240
241 // We already checked for TYPE_NULL. This should never happen.
242 throw new RuntimeException("getText of bad type: 0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243 }
244
245 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800246 * Retrieves the string value for the attribute at <var>index</var>.
247 * <p>
248 * If the attribute is not a string, this method will attempt to coerce
249 * it to a string.
Alan Viverettefd274a02014-03-27 15:39:15 -0700250 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -0700252 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800253 * @return String holding string data. Any styling information is removed.
254 * Returns {@code null} if the attribute is not defined or could
255 * not be coerced to a string.
256 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800257 */
Alan Viverettea6f354b2015-05-18 15:26:57 -0700258 @Nullable
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700259 public String getString(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700260 if (mRecycled) {
261 throw new RuntimeException("Cannot make calls to a recycled instance!");
262 }
263
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800264 index *= STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800266 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267 if (type == TypedValue.TYPE_NULL) {
268 return null;
269 } else if (type == TypedValue.TYPE_STRING) {
270 return loadStringValueAt(index).toString();
271 }
272
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800273 final TypedValue v = mValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274 if (getValueAt(index, v)) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800275 final CharSequence cs = v.coerceToString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 return cs != null ? cs.toString() : null;
277 }
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800278
279 // We already checked for TYPE_NULL. This should never happen.
280 throw new RuntimeException("getString of bad type: 0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281 }
282
283 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800284 * Retrieves the string value for the attribute at <var>index</var>, but
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285 * only if that string comes from an immediate value in an XML file. That
286 * is, this does not allow references to string resources, string
287 * attributes, or conversions from other types. As such, this method
288 * will only return strings for TypedArray objects that come from
289 * attributes in an XML file.
Alan Viverettefd274a02014-03-27 15:39:15 -0700290 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -0700292 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800293 * @return String holding string data. Any styling information is removed.
294 * Returns {@code null} if the attribute is not defined or is not
295 * an immediate string value.
296 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700298 public String getNonResourceString(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700299 if (mRecycled) {
300 throw new RuntimeException("Cannot make calls to a recycled instance!");
301 }
302
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800303 index *= STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800305 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 if (type == TypedValue.TYPE_STRING) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800307 final int cookie = data[index + STYLE_ASSET_COOKIE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308 if (cookie < 0) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800309 return mXml.getPooledString(data[index + STYLE_DATA]).toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 }
311 }
312 return null;
313 }
Alan Viverettefd274a02014-03-27 15:39:15 -0700314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800316 * Retrieves the string value for the attribute at <var>index</var> that is
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800317 * not allowed to change with the given configurations.
Alan Viverettefd274a02014-03-27 15:39:15 -0700318 *
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800319 * @param index Index of attribute to retrieve.
320 * @param allowedChangingConfigs Bit mask of configurations from
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800321 * {@link Configuration}.NATIVE_CONFIG_* that are allowed to change.
Dianne Hackborn1d0b1772013-09-06 14:02:54 -0700322 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800323 * @return String holding string data. Any styling information is removed.
324 * Returns {@code null} if the attribute is not defined.
325 * @throws RuntimeException if the TypedArray has already been recycled.
326 * @hide
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800327 */
Mathew Inwood5c0d3542018-08-14 13:54:31 +0100328 @UnsupportedAppUsage
Alan Viveretteac85f902016-03-11 15:15:51 -0500329 public String getNonConfigurationString(@StyleableRes int index,
330 @Config int allowedChangingConfigs) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700331 if (mRecycled) {
332 throw new RuntimeException("Cannot make calls to a recycled instance!");
333 }
334
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800335 index *= STYLE_NUM_ENTRIES;
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800336 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800337 final int type = data[index + STYLE_TYPE];
Alan Viveretteac85f902016-03-11 15:15:51 -0500338 final @Config int changingConfigs = ActivityInfo.activityInfoConfigNativeToJava(
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800339 data[index + STYLE_CHANGING_CONFIGURATIONS]);
Alan Viveretteac85f902016-03-11 15:15:51 -0500340 if ((changingConfigs & ~allowedChangingConfigs) != 0) {
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800341 return null;
342 }
343 if (type == TypedValue.TYPE_NULL) {
344 return null;
345 } else if (type == TypedValue.TYPE_STRING) {
346 return loadStringValueAt(index).toString();
347 }
348
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800349 final TypedValue v = mValue;
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800350 if (getValueAt(index, v)) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800351 final CharSequence cs = v.coerceToString();
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800352 return cs != null ? cs.toString() : null;
353 }
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800354
355 // We already checked for TYPE_NULL. This should never happen.
356 throw new RuntimeException("getNonConfigurationString of bad type: 0x"
357 + Integer.toHexString(type));
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800358 }
359
360 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800361 * Retrieve the boolean value for the attribute at <var>index</var>.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800362 * <p>
363 * If the attribute is an integer value, this method will return whether
364 * it is equal to zero. If the attribute is not a boolean or integer value,
365 * this method will attempt to coerce it to an integer using
366 * {@link Integer#decode(String)} and return whether it is equal to zero.
Alan Viverettefd274a02014-03-27 15:39:15 -0700367 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368 * @param index Index of attribute to retrieve.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800369 * @param defValue Value to return if the attribute is not defined or
370 * cannot be coerced to an integer.
Alan Viverettefd274a02014-03-27 15:39:15 -0700371 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800372 * @return Boolean value of the attribute, or defValue if the attribute was
373 * not defined or could not be coerced to an integer.
374 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800375 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700376 public boolean getBoolean(@StyleableRes int index, boolean defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700377 if (mRecycled) {
378 throw new RuntimeException("Cannot make calls to a recycled instance!");
379 }
380
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800381 index *= STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800383 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384 if (type == TypedValue.TYPE_NULL) {
385 return defValue;
386 } else if (type >= TypedValue.TYPE_FIRST_INT
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800387 && type <= TypedValue.TYPE_LAST_INT) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800388 return data[index + STYLE_DATA] != 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 }
390
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800391 final TypedValue v = mValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392 if (getValueAt(index, v)) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800393 StrictMode.noteResourceMismatch(v);
394 return XmlUtils.convertValueToBoolean(v.coerceToString(), defValue);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 }
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800396
397 // We already checked for TYPE_NULL. This should never happen.
398 throw new RuntimeException("getBoolean of bad type: 0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 }
400
401 /**
402 * Retrieve the integer value for the attribute at <var>index</var>.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800403 * <p>
404 * If the attribute is not an integer, this method will attempt to coerce
405 * it to an integer using {@link Integer#decode(String)}.
Alan Viverettefd274a02014-03-27 15:39:15 -0700406 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800407 * @param index Index of attribute to retrieve.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800408 * @param defValue Value to return if the attribute is not defined or
409 * cannot be coerced to an integer.
Alan Viverettefd274a02014-03-27 15:39:15 -0700410 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800411 * @return Integer value of the attribute, or defValue if the attribute was
412 * not defined or could not be coerced to an integer.
413 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700415 public int getInt(@StyleableRes int index, int defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700416 if (mRecycled) {
417 throw new RuntimeException("Cannot make calls to a recycled instance!");
418 }
419
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800420 index *= STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800421 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800422 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800423 if (type == TypedValue.TYPE_NULL) {
424 return defValue;
425 } else if (type >= TypedValue.TYPE_FIRST_INT
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800426 && type <= TypedValue.TYPE_LAST_INT) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800427 return data[index + STYLE_DATA];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800428 }
429
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800430 final TypedValue v = mValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800431 if (getValueAt(index, v)) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800432 StrictMode.noteResourceMismatch(v);
433 return XmlUtils.convertValueToInt(v.coerceToString(), defValue);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800434 }
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800435
436 // We already checked for TYPE_NULL. This should never happen.
437 throw new RuntimeException("getInt of bad type: 0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800438 }
439
440 /**
441 * Retrieve the float value for the attribute at <var>index</var>.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800442 * <p>
443 * If the attribute is not a float or an integer, this method will attempt
444 * to coerce it to a float using {@link Float#parseFloat(String)}.
Alan Viverettefd274a02014-03-27 15:39:15 -0700445 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800446 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -0700447 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800448 * @return Attribute float value, or defValue if the attribute was
449 * not defined or could not be coerced to a float.
450 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700452 public float getFloat(@StyleableRes int index, float defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700453 if (mRecycled) {
454 throw new RuntimeException("Cannot make calls to a recycled instance!");
455 }
456
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800457 index *= STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800459 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800460 if (type == TypedValue.TYPE_NULL) {
461 return defValue;
462 } else if (type == TypedValue.TYPE_FLOAT) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800463 return Float.intBitsToFloat(data[index + STYLE_DATA]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800464 } else if (type >= TypedValue.TYPE_FIRST_INT
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800465 && type <= TypedValue.TYPE_LAST_INT) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800466 return data[index + STYLE_DATA];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800467 }
468
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800469 final TypedValue v = mValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470 if (getValueAt(index, v)) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800471 final CharSequence str = v.coerceToString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800472 if (str != null) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800473 StrictMode.noteResourceMismatch(v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 return Float.parseFloat(str.toString());
475 }
476 }
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800477
478 // We already checked for TYPE_NULL. This should never happen.
479 throw new RuntimeException("getFloat of bad type: 0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800480 }
Alan Viverettefd274a02014-03-27 15:39:15 -0700481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800482 /**
483 * Retrieve the color value for the attribute at <var>index</var>. If
484 * the attribute references a color resource holding a complex
485 * {@link android.content.res.ColorStateList}, then the default color from
486 * the set is returned.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800487 * <p>
488 * This method will throw an exception if the attribute is defined but is
489 * not an integer color or color state list.
Alan Viverettefd274a02014-03-27 15:39:15 -0700490 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800491 * @param index Index of attribute to retrieve.
492 * @param defValue Value to return if the attribute is not defined or
493 * not a resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700494 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 * @return Attribute color value, or defValue if not defined.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800496 * @throws RuntimeException if the TypedArray has already been recycled.
497 * @throws UnsupportedOperationException if the attribute is defined but is
498 * not an integer color or color state list.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800499 */
Tor Norbye80756e32015-03-02 09:39:27 -0800500 @ColorInt
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700501 public int getColor(@StyleableRes int index, @ColorInt int defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700502 if (mRecycled) {
503 throw new RuntimeException("Cannot make calls to a recycled instance!");
504 }
505
Alan Viverette5b90e822016-02-24 09:06:47 -0500506 final int attrIndex = index;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800507 index *= STYLE_NUM_ENTRIES;
Alan Viverette5b90e822016-02-24 09:06:47 -0500508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800510 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800511 if (type == TypedValue.TYPE_NULL) {
512 return defValue;
513 } else if (type >= TypedValue.TYPE_FIRST_INT
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800514 && type <= TypedValue.TYPE_LAST_INT) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800515 return data[index + STYLE_DATA];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800516 } else if (type == TypedValue.TYPE_STRING) {
517 final TypedValue value = mValue;
518 if (getValueAt(index, value)) {
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800519 final ColorStateList csl = mResources.loadColorStateList(
520 value, value.resourceId, mTheme);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800521 return csl.getDefaultColor();
522 }
523 return defValue;
Alan Viverette216d3e62014-07-29 10:35:42 -0700524 } else if (type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette93795052015-03-09 15:32:50 -0700525 final TypedValue value = mValue;
Alan Viverette5b90e822016-02-24 09:06:47 -0500526 getValueAt(index, value);
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800527 throw new UnsupportedOperationException(
Alan Viverette5b90e822016-02-24 09:06:47 -0500528 "Failed to resolve attribute at index " + attrIndex + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800529 }
530
Alan Viverette5b90e822016-02-24 09:06:47 -0500531 throw new UnsupportedOperationException("Can't convert value at index " + attrIndex
532 + " to color: type=0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800533 }
534
535 /**
Teng-Hui Zhudbee9bb2015-12-15 11:01:27 -0800536 * Retrieve the ComplexColor for the attribute at <var>index</var>.
537 * The value may be either a {@link android.content.res.ColorStateList} which can wrap a simple
538 * color value or a {@link android.content.res.GradientColor}
539 * <p>
540 * This method will return {@code null} if the attribute is not defined or
541 * is not an integer color, color state list or GradientColor.
542 *
543 * @param index Index of attribute to retrieve.
544 *
545 * @return ComplexColor for the attribute, or {@code null} if not defined.
546 * @throws RuntimeException if the attribute if the TypedArray has already
547 * been recycled.
548 * @throws UnsupportedOperationException if the attribute is defined but is
549 * not an integer color, color state list or GradientColor.
Teng-Hui Zhue03c4692016-03-17 10:38:43 -0700550 * @hide
Teng-Hui Zhudbee9bb2015-12-15 11:01:27 -0800551 */
552 @Nullable
553 public ComplexColor getComplexColor(@StyleableRes int index) {
554 if (mRecycled) {
555 throw new RuntimeException("Cannot make calls to a recycled instance!");
556 }
557
558 final TypedValue value = mValue;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800559 if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
Teng-Hui Zhudbee9bb2015-12-15 11:01:27 -0800560 if (value.type == TypedValue.TYPE_ATTRIBUTE) {
561 throw new UnsupportedOperationException(
562 "Failed to resolve attribute at index " + index + ": " + value);
563 }
564 return mResources.loadComplexColor(value, value.resourceId, mTheme);
565 }
566 return null;
567 }
568
569 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800570 * Retrieve the ColorStateList for the attribute at <var>index</var>.
571 * The value may be either a single solid color or a reference to
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800572 * a color or complex {@link android.content.res.ColorStateList}
573 * description.
574 * <p>
575 * This method will return {@code null} if the attribute is not defined or
576 * is not an integer color or color state list.
Alan Viverettefd274a02014-03-27 15:39:15 -0700577 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -0700579 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800580 * @return ColorStateList for the attribute, or {@code null} if not
581 * defined.
582 * @throws RuntimeException if the attribute if the TypedArray has already
583 * been recycled.
584 * @throws UnsupportedOperationException if the attribute is defined but is
585 * not an integer color or color state list.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586 */
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800587 @Nullable
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700588 public ColorStateList getColorStateList(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700589 if (mRecycled) {
590 throw new RuntimeException("Cannot make calls to a recycled instance!");
591 }
592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593 final TypedValue value = mValue;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800594 if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
Alan Viverette216d3e62014-07-29 10:35:42 -0700595 if (value.type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800596 throw new UnsupportedOperationException(
Alan Viverette93795052015-03-09 15:32:50 -0700597 "Failed to resolve attribute at index " + index + ": " + value);
Alan Viverette216d3e62014-07-29 10:35:42 -0700598 }
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800599 return mResources.loadColorStateList(value, value.resourceId, mTheme);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800600 }
601 return null;
602 }
603
604 /**
605 * Retrieve the integer value for the attribute at <var>index</var>.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800606 * <p>
607 * Unlike {@link #getInt(int, int)}, this method will throw an exception if
608 * the attribute is defined but is not an integer.
Alan Viverettefd274a02014-03-27 15:39:15 -0700609 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800610 * @param index Index of attribute to retrieve.
611 * @param defValue Value to return if the attribute is not defined or
612 * not a resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700613 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800614 * @return Attribute integer value, or defValue if not defined.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800615 * @throws RuntimeException if the TypedArray has already been recycled.
616 * @throws UnsupportedOperationException if the attribute is defined but is
617 * not an integer.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800618 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700619 public int getInteger(@StyleableRes int index, int defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700620 if (mRecycled) {
621 throw new RuntimeException("Cannot make calls to a recycled instance!");
622 }
623
Alan Viverette5b90e822016-02-24 09:06:47 -0500624 final int attrIndex = index;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800625 index *= STYLE_NUM_ENTRIES;
Alan Viverette5b90e822016-02-24 09:06:47 -0500626
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800627 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800628 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629 if (type == TypedValue.TYPE_NULL) {
630 return defValue;
631 } else if (type >= TypedValue.TYPE_FIRST_INT
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800632 && type <= TypedValue.TYPE_LAST_INT) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800633 return data[index + STYLE_DATA];
Alan Viverette216d3e62014-07-29 10:35:42 -0700634 } else if (type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette93795052015-03-09 15:32:50 -0700635 final TypedValue value = mValue;
Alan Viverette5b90e822016-02-24 09:06:47 -0500636 getValueAt(index, value);
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800637 throw new UnsupportedOperationException(
Alan Viverette5b90e822016-02-24 09:06:47 -0500638 "Failed to resolve attribute at index " + attrIndex + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800639 }
640
Alan Viverette5b90e822016-02-24 09:06:47 -0500641 throw new UnsupportedOperationException("Can't convert value at index " + attrIndex
642 + " to integer: type=0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800643 }
644
645 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800646 * Retrieve a dimensional unit attribute at <var>index</var>. Unit
Alan Viverettefd274a02014-03-27 15:39:15 -0700647 * conversions are based on the current {@link DisplayMetrics}
648 * associated with the resources this {@link TypedArray} object
649 * came from.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800650 * <p>
651 * This method will throw an exception if the attribute is defined but is
652 * not a dimension.
Alan Viverettefd274a02014-03-27 15:39:15 -0700653 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800654 * @param index Index of attribute to retrieve.
655 * @param defValue Value to return if the attribute is not defined or
656 * not a resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700657 *
658 * @return Attribute dimension value multiplied by the appropriate
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800659 * metric, or defValue if not defined.
660 * @throws RuntimeException if the TypedArray has already been recycled.
661 * @throws UnsupportedOperationException if the attribute is defined but is
662 * not an integer.
Alan Viverettefd274a02014-03-27 15:39:15 -0700663 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800664 * @see #getDimensionPixelOffset
665 * @see #getDimensionPixelSize
666 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700667 public float getDimension(@StyleableRes int index, float defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700668 if (mRecycled) {
669 throw new RuntimeException("Cannot make calls to a recycled instance!");
670 }
671
Alan Viverette5b90e822016-02-24 09:06:47 -0500672 final int attrIndex = index;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800673 index *= STYLE_NUM_ENTRIES;
Alan Viverette5b90e822016-02-24 09:06:47 -0500674
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800675 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800676 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800677 if (type == TypedValue.TYPE_NULL) {
678 return defValue;
679 } else if (type == TypedValue.TYPE_DIMENSION) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800680 return TypedValue.complexToDimension(data[index + STYLE_DATA], mMetrics);
Alan Viverette216d3e62014-07-29 10:35:42 -0700681 } else if (type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette93795052015-03-09 15:32:50 -0700682 final TypedValue value = mValue;
Alan Viverette5b90e822016-02-24 09:06:47 -0500683 getValueAt(index, value);
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800684 throw new UnsupportedOperationException(
Alan Viverette5b90e822016-02-24 09:06:47 -0500685 "Failed to resolve attribute at index " + attrIndex + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800686 }
687
Alan Viverette5b90e822016-02-24 09:06:47 -0500688 throw new UnsupportedOperationException("Can't convert value at index " + attrIndex
689 + " to dimension: type=0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800690 }
691
692 /**
693 * Retrieve a dimensional unit attribute at <var>index</var> for use
694 * as an offset in raw pixels. This is the same as
695 * {@link #getDimension}, except the returned value is converted to
696 * integer pixels for you. An offset conversion involves simply
697 * truncating the base value to an integer.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800698 * <p>
699 * This method will throw an exception if the attribute is defined but is
700 * not a dimension.
Alan Viverettefd274a02014-03-27 15:39:15 -0700701 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800702 * @param index Index of attribute to retrieve.
703 * @param defValue Value to return if the attribute is not defined or
704 * not a resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700705 *
706 * @return Attribute dimension value multiplied by the appropriate
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800707 * metric and truncated to integer pixels, or defValue if not defined.
708 * @throws RuntimeException if the TypedArray has already been recycled.
709 * @throws UnsupportedOperationException if the attribute is defined but is
710 * not an integer.
Alan Viverettefd274a02014-03-27 15:39:15 -0700711 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800712 * @see #getDimension
713 * @see #getDimensionPixelSize
714 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700715 public int getDimensionPixelOffset(@StyleableRes int index, int defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700716 if (mRecycled) {
717 throw new RuntimeException("Cannot make calls to a recycled instance!");
718 }
719
Alan Viverette5b90e822016-02-24 09:06:47 -0500720 final int attrIndex = index;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800721 index *= STYLE_NUM_ENTRIES;
Alan Viverette5b90e822016-02-24 09:06:47 -0500722
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800724 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800725 if (type == TypedValue.TYPE_NULL) {
726 return defValue;
727 } else if (type == TypedValue.TYPE_DIMENSION) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800728 return TypedValue.complexToDimensionPixelOffset(data[index + STYLE_DATA], mMetrics);
Alan Viverette216d3e62014-07-29 10:35:42 -0700729 } else if (type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette93795052015-03-09 15:32:50 -0700730 final TypedValue value = mValue;
Alan Viverette5b90e822016-02-24 09:06:47 -0500731 getValueAt(index, value);
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800732 throw new UnsupportedOperationException(
Alan Viverette5b90e822016-02-24 09:06:47 -0500733 "Failed to resolve attribute at index " + attrIndex + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800734 }
735
Alan Viverette5b90e822016-02-24 09:06:47 -0500736 throw new UnsupportedOperationException("Can't convert value at index " + attrIndex
737 + " to dimension: type=0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800738 }
739
740 /**
741 * Retrieve a dimensional unit attribute at <var>index</var> for use
742 * as a size in raw pixels. This is the same as
743 * {@link #getDimension}, except the returned value is converted to
744 * integer pixels for use as a size. A size conversion involves
745 * rounding the base value, and ensuring that a non-zero base value
746 * is at least one pixel in size.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800747 * <p>
748 * This method will throw an exception if the attribute is defined but is
749 * not a dimension.
Alan Viverettefd274a02014-03-27 15:39:15 -0700750 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800751 * @param index Index of attribute to retrieve.
752 * @param defValue Value to return if the attribute is not defined or
753 * not a resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700754 *
755 * @return Attribute dimension value multiplied by the appropriate
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800756 * metric and truncated to integer pixels, or defValue if not defined.
757 * @throws RuntimeException if the TypedArray has already been recycled.
758 * @throws UnsupportedOperationException if the attribute is defined but is
759 * not a dimension.
Alan Viverettefd274a02014-03-27 15:39:15 -0700760 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800761 * @see #getDimension
762 * @see #getDimensionPixelOffset
763 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700764 public int getDimensionPixelSize(@StyleableRes int index, int defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700765 if (mRecycled) {
766 throw new RuntimeException("Cannot make calls to a recycled instance!");
767 }
768
Alan Viverette5b90e822016-02-24 09:06:47 -0500769 final int attrIndex = index;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800770 index *= STYLE_NUM_ENTRIES;
Alan Viverette5b90e822016-02-24 09:06:47 -0500771
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800772 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800773 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800774 if (type == TypedValue.TYPE_NULL) {
775 return defValue;
776 } else if (type == TypedValue.TYPE_DIMENSION) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800777 return TypedValue.complexToDimensionPixelSize(data[index + STYLE_DATA], mMetrics);
Alan Viverette216d3e62014-07-29 10:35:42 -0700778 } else if (type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette93795052015-03-09 15:32:50 -0700779 final TypedValue value = mValue;
Alan Viverette5b90e822016-02-24 09:06:47 -0500780 getValueAt(index, value);
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800781 throw new UnsupportedOperationException(
Alan Viverette5b90e822016-02-24 09:06:47 -0500782 "Failed to resolve attribute at index " + attrIndex + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800783 }
784
Alan Viverette5b90e822016-02-24 09:06:47 -0500785 throw new UnsupportedOperationException("Can't convert value at index " + attrIndex
786 + " to dimension: type=0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800787 }
788
789 /**
790 * Special version of {@link #getDimensionPixelSize} for retrieving
791 * {@link android.view.ViewGroup}'s layout_width and layout_height
792 * attributes. This is only here for performance reasons; applications
793 * should use {@link #getDimensionPixelSize}.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800794 * <p>
795 * This method will throw an exception if the attribute is defined but is
796 * not a dimension or integer (enum).
Alan Viverettefd274a02014-03-27 15:39:15 -0700797 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800798 * @param index Index of the attribute to retrieve.
799 * @param name Textual name of attribute for error reporting.
Alan Viverettefd274a02014-03-27 15:39:15 -0700800 *
801 * @return Attribute dimension value multiplied by the appropriate
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800802 * metric and truncated to integer pixels.
803 * @throws RuntimeException if the TypedArray has already been recycled.
804 * @throws UnsupportedOperationException if the attribute is defined but is
805 * not a dimension or integer (enum).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800806 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700807 public int getLayoutDimension(@StyleableRes int index, String name) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700808 if (mRecycled) {
809 throw new RuntimeException("Cannot make calls to a recycled instance!");
810 }
811
Alan Viverette5b90e822016-02-24 09:06:47 -0500812 final int attrIndex = index;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800813 index *= STYLE_NUM_ENTRIES;
Alan Viverette5b90e822016-02-24 09:06:47 -0500814
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800815 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800816 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800817 if (type >= TypedValue.TYPE_FIRST_INT
818 && type <= TypedValue.TYPE_LAST_INT) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800819 return data[index + STYLE_DATA];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800820 } else if (type == TypedValue.TYPE_DIMENSION) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800821 return TypedValue.complexToDimensionPixelSize(data[index + STYLE_DATA], mMetrics);
Alan Viverette216d3e62014-07-29 10:35:42 -0700822 } else if (type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette93795052015-03-09 15:32:50 -0700823 final TypedValue value = mValue;
Alan Viverette5b90e822016-02-24 09:06:47 -0500824 getValueAt(index, value);
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800825 throw new UnsupportedOperationException(
Alan Viverette5b90e822016-02-24 09:06:47 -0500826 "Failed to resolve attribute at index " + attrIndex + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800827 }
828
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800829 throw new UnsupportedOperationException(getPositionDescription()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 + ": You must supply a " + name + " attribute.");
831 }
Alan Viverettefd274a02014-03-27 15:39:15 -0700832
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800833 /**
834 * Special version of {@link #getDimensionPixelSize} for retrieving
835 * {@link android.view.ViewGroup}'s layout_width and layout_height
836 * attributes. This is only here for performance reasons; applications
837 * should use {@link #getDimensionPixelSize}.
Alan Viverettefd274a02014-03-27 15:39:15 -0700838 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839 * @param index Index of the attribute to retrieve.
840 * @param defValue The default value to return if this attribute is not
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800841 * default or contains the wrong type of data.
Alan Viverettefd274a02014-03-27 15:39:15 -0700842 *
843 * @return Attribute dimension value multiplied by the appropriate
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800844 * metric and truncated to integer pixels.
845 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800846 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700847 public int getLayoutDimension(@StyleableRes int index, int defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700848 if (mRecycled) {
849 throw new RuntimeException("Cannot make calls to a recycled instance!");
850 }
851
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800852 index *= STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800853 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800854 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800855 if (type >= TypedValue.TYPE_FIRST_INT
856 && type <= TypedValue.TYPE_LAST_INT) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800857 return data[index + STYLE_DATA];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800858 } else if (type == TypedValue.TYPE_DIMENSION) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800859 return TypedValue.complexToDimensionPixelSize(data[index + STYLE_DATA], mMetrics);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800860 }
861
862 return defValue;
863 }
864
865 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800866 * Retrieves a fractional unit attribute at <var>index</var>.
Alan Viverettefd274a02014-03-27 15:39:15 -0700867 *
868 * @param index Index of attribute to retrieve.
869 * @param base The base value of this fraction. In other words, a
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800870 * standard fraction is multiplied by this value.
Alan Viverettefd274a02014-03-27 15:39:15 -0700871 * @param pbase The parent base value of this fraction. In other
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800872 * words, a parent fraction (nn%p) is multiplied by this
873 * value.
874 * @param defValue Value to return if the attribute is not defined or
875 * not a resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700876 *
877 * @return Attribute fractional value multiplied by the appropriate
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800878 * base value, or defValue if not defined.
879 * @throws RuntimeException if the TypedArray has already been recycled.
880 * @throws UnsupportedOperationException if the attribute is defined but is
881 * not a fraction.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800882 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700883 public float getFraction(@StyleableRes int index, int base, int pbase, float defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700884 if (mRecycled) {
885 throw new RuntimeException("Cannot make calls to a recycled instance!");
886 }
887
Alan Viverette5b90e822016-02-24 09:06:47 -0500888 final int attrIndex = index;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800889 index *= STYLE_NUM_ENTRIES;
Alan Viverette5b90e822016-02-24 09:06:47 -0500890
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800891 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800892 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800893 if (type == TypedValue.TYPE_NULL) {
894 return defValue;
895 } else if (type == TypedValue.TYPE_FRACTION) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800896 return TypedValue.complexToFraction(data[index + STYLE_DATA], base, pbase);
Alan Viverette216d3e62014-07-29 10:35:42 -0700897 } else if (type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette93795052015-03-09 15:32:50 -0700898 final TypedValue value = mValue;
Alan Viverette5b90e822016-02-24 09:06:47 -0500899 getValueAt(index, value);
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800900 throw new UnsupportedOperationException(
Alan Viverette5b90e822016-02-24 09:06:47 -0500901 "Failed to resolve attribute at index " + attrIndex + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800902 }
903
Alan Viverette5b90e822016-02-24 09:06:47 -0500904 throw new UnsupportedOperationException("Can't convert value at index " + attrIndex
905 + " to fraction: type=0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800906 }
907
908 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800909 * Retrieves the resource identifier for the attribute at
Alan Viverettefd274a02014-03-27 15:39:15 -0700910 * <var>index</var>. Note that attribute resource as resolved when
911 * the overall {@link TypedArray} object is retrieved. As a
912 * result, this function will return the resource identifier of the
913 * final resource value that was found, <em>not</em> necessarily the
914 * original resource that was specified by the attribute.
915 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800916 * @param index Index of attribute to retrieve.
917 * @param defValue Value to return if the attribute is not defined or
918 * not a resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700919 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800920 * @return Attribute resource identifier, or defValue if not defined.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800921 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800922 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700923 @AnyRes
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700924 public int getResourceId(@StyleableRes int index, int defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700925 if (mRecycled) {
926 throw new RuntimeException("Cannot make calls to a recycled instance!");
927 }
928
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800929 index *= STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800931 if (data[index + STYLE_TYPE] != TypedValue.TYPE_NULL) {
932 final int resid = data[index + STYLE_RESOURCE_ID];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933 if (resid != 0) {
934 return resid;
935 }
936 }
937 return defValue;
938 }
939
940 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800941 * Retrieves the theme attribute resource identifier for the attribute at
Alan Viverette500c5602014-07-29 11:30:35 -0700942 * <var>index</var>.
943 *
944 * @param index Index of attribute to retrieve.
945 * @param defValue Value to return if the attribute is not defined or not a
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800946 * resource.
947 *
Alan Viverette500c5602014-07-29 11:30:35 -0700948 * @return Theme attribute resource identifier, or defValue if not defined.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800949 * @throws RuntimeException if the TypedArray has already been recycled.
Alan Viverette500c5602014-07-29 11:30:35 -0700950 * @hide
951 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700952 public int getThemeAttributeId(@StyleableRes int index, int defValue) {
Alan Viverette500c5602014-07-29 11:30:35 -0700953 if (mRecycled) {
954 throw new RuntimeException("Cannot make calls to a recycled instance!");
955 }
956
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800957 index *= STYLE_NUM_ENTRIES;
Alan Viverette500c5602014-07-29 11:30:35 -0700958 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800959 if (data[index + STYLE_TYPE] == TypedValue.TYPE_ATTRIBUTE) {
960 return data[index + STYLE_DATA];
Alan Viverette500c5602014-07-29 11:30:35 -0700961 }
962 return defValue;
963 }
964
965 /**
Alan Viverettefde4e3b2014-09-22 16:19:51 -0700966 * Retrieve the Drawable for the attribute at <var>index</var>.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800967 * <p>
968 * This method will throw an exception if the attribute is defined but is
969 * not a color or drawable resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700970 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800971 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -0700972 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800973 * @return Drawable for the attribute, or {@code null} if not defined.
974 * @throws RuntimeException if the TypedArray has already been recycled.
975 * @throws UnsupportedOperationException if the attribute is defined but is
976 * not a color or drawable resource.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800977 */
Alan Viverettefde4e3b2014-09-22 16:19:51 -0700978 @Nullable
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700979 public Drawable getDrawable(@StyleableRes int index) {
Adam Lesinski50954d22017-04-14 18:41:52 -0700980 return getDrawableForDensity(index, 0);
981 }
982
983 /**
984 * Version of {@link #getDrawable(int)} that accepts an override density.
985 * @hide
986 */
987 @Nullable
988 public Drawable getDrawableForDensity(@StyleableRes int index, int density) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700989 if (mRecycled) {
990 throw new RuntimeException("Cannot make calls to a recycled instance!");
991 }
992
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800993 final TypedValue value = mValue;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800994 if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
Alan Viverette216d3e62014-07-29 10:35:42 -0700995 if (value.type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800996 throw new UnsupportedOperationException(
Alan Viverette93795052015-03-09 15:32:50 -0700997 "Failed to resolve attribute at index " + index + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800998 }
Adam Lesinski50954d22017-04-14 18:41:52 -0700999
1000 if (density > 0) {
1001 // If the density is overridden, the value in the TypedArray will not reflect this.
1002 // Do a separate lookup of the resourceId with the density override.
1003 mResources.getValueForDensity(value.resourceId, density, value, true);
1004 }
1005 return mResources.loadDrawable(value, value.resourceId, density, mTheme);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001006 }
1007 return null;
1008 }
1009
1010 /**
Clara Bayarried00bfd2017-01-20 14:58:21 +00001011 * Retrieve the Typeface for the attribute at <var>index</var>.
1012 * <p>
1013 * This method will throw an exception if the attribute is defined but is
1014 * not a font.
1015 *
1016 * @param index Index of attribute to retrieve.
1017 *
1018 * @return Typeface for the attribute, or {@code null} if not defined.
1019 * @throws RuntimeException if the TypedArray has already been recycled.
1020 * @throws UnsupportedOperationException if the attribute is defined but is
1021 * not a font resource.
1022 */
1023 @Nullable
1024 public Typeface getFont(@StyleableRes int index) {
1025 if (mRecycled) {
1026 throw new RuntimeException("Cannot make calls to a recycled instance!");
1027 }
1028
1029 final TypedValue value = mValue;
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001030 if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
Clara Bayarried00bfd2017-01-20 14:58:21 +00001031 if (value.type == TypedValue.TYPE_ATTRIBUTE) {
1032 throw new UnsupportedOperationException(
1033 "Failed to resolve attribute at index " + index + ": " + value);
1034 }
1035 return mResources.getFont(value, value.resourceId);
1036 }
1037 return null;
1038 }
1039
1040 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001041 * Retrieve the CharSequence[] for the attribute at <var>index</var>.
1042 * This gets the resource ID of the selected attribute, and uses
1043 * {@link Resources#getTextArray Resources.getTextArray} of the owning
1044 * Resources object to retrieve its String[].
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001045 * <p>
1046 * This method will throw an exception if the attribute is defined but is
1047 * not a text array resource.
Alan Viverettefd274a02014-03-27 15:39:15 -07001048 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001049 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -07001050 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001051 * @return CharSequence[] for the attribute, or {@code null} if not
1052 * defined.
1053 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001054 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -07001055 public CharSequence[] getTextArray(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -07001056 if (mRecycled) {
1057 throw new RuntimeException("Cannot make calls to a recycled instance!");
1058 }
1059
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001060 final TypedValue value = mValue;
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001061 if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001062 return mResources.getTextArray(value.resourceId);
1063 }
1064 return null;
1065 }
1066
1067 /**
1068 * Retrieve the raw TypedValue for the attribute at <var>index</var>.
Alan Viverettefd274a02014-03-27 15:39:15 -07001069 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001070 * @param index Index of attribute to retrieve.
1071 * @param outValue TypedValue object in which to place the attribute's
1072 * data.
Alan Viverettefd274a02014-03-27 15:39:15 -07001073 *
Adam Lesinski32e75012017-05-09 15:25:37 -07001074 * @return {@code true} if the value was retrieved and not @empty, {@code false} otherwise.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001075 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001076 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -07001077 public boolean getValue(@StyleableRes int index, TypedValue outValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -07001078 if (mRecycled) {
1079 throw new RuntimeException("Cannot make calls to a recycled instance!");
Alan Viverette52b999f2014-03-24 18:00:26 -07001080 }
Alan Viverettefd274a02014-03-27 15:39:15 -07001081
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001082 return getValueAt(index * STYLE_NUM_ENTRIES, outValue);
Alan Viverette52b999f2014-03-24 18:00:26 -07001083 }
1084
1085 /**
1086 * Returns the type of attribute at the specified index.
1087 *
1088 * @param index Index of attribute whose type to retrieve.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001089 *
Alan Viverette52b999f2014-03-24 18:00:26 -07001090 * @return Attribute type.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001091 * @throws RuntimeException if the TypedArray has already been recycled.
Alan Viverette52b999f2014-03-24 18:00:26 -07001092 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -07001093 public int getType(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -07001094 if (mRecycled) {
1095 throw new RuntimeException("Cannot make calls to a recycled instance!");
1096 }
1097
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001098 index *= STYLE_NUM_ENTRIES;
1099 return mData[index + STYLE_TYPE];
Alan Viverette52b999f2014-03-24 18:00:26 -07001100 }
1101
1102 /**
Aurimas Liutikas949b05d2019-01-30 17:20:41 -08001103 * Returns the resource ID of the style or layout against which the specified attribute was
1104 * resolved, otherwise returns defValue.
1105 *
1106 * For example, if you we resolving two attributes {@code android:attribute1} and
1107 * {@code android:attribute2} and you were inflating a {@link android.view.View} from
1108 * {@code layout/my_layout.xml}:
1109 * <pre>
1110 * &lt;View
1111 * style="@style/viewStyle"
1112 * android:layout_width="wrap_content"
1113 * android:layout_height="wrap_content"
1114 * android:attribute1="foo"/&gt;
1115 * </pre>
1116 *
1117 * and {@code @style/viewStyle} is:
1118 * <pre>
1119 * &lt;style android:name="viewStyle"&gt;
1120 * &lt;item name="android:attribute2"&gt;bar&lt;item/&gt;
1121 * &lt;style/&gt;
1122 * </pre>
1123 *
1124 * then resolved {@link TypedArray} will have values that return source resource ID of
1125 * {@code R.layout.my_layout} for {@code android:attribute1} and {@code R.style.viewStyle} for
1126 * {@code android:attribute2}.
Aurimas Liutikasce7c99c2018-12-18 16:20:49 -08001127 *
1128 * @param index Index of attribute whose source style to retrieve.
Aurimas Liutikas949b05d2019-01-30 17:20:41 -08001129 * @param defaultValue Value to return if the attribute is not defined or
1130 * not a resource.
Aurimas Liutikasce7c99c2018-12-18 16:20:49 -08001131 *
Aurimas Liutikas949b05d2019-01-30 17:20:41 -08001132 * @return Either a style resource ID, layout resource ID, or defaultValue if it was not
1133 * resolved in a style or layout.
Aurimas Liutikasce7c99c2018-12-18 16:20:49 -08001134 * @throws RuntimeException if the TypedArray has already been recycled.
1135 */
Aurimas Liutikasf9dbd5f2019-03-07 11:21:51 -08001136 @AnyRes
1137 public int getSourceResourceId(@StyleableRes int index, @AnyRes int defaultValue) {
Aurimas Liutikasce7c99c2018-12-18 16:20:49 -08001138 if (mRecycled) {
1139 throw new RuntimeException("Cannot make calls to a recycled instance!");
1140 }
1141
1142 index *= STYLE_NUM_ENTRIES;
Aurimas Liutikasf9dbd5f2019-03-07 11:21:51 -08001143 final int resid = mData[index + STYLE_SOURCE_RESOURCE_ID];
Aurimas Liutikasce7c99c2018-12-18 16:20:49 -08001144 if (resid != 0) {
1145 return resid;
1146 }
Aurimas Liutikas949b05d2019-01-30 17:20:41 -08001147 return defaultValue;
Aurimas Liutikasce7c99c2018-12-18 16:20:49 -08001148 }
1149
1150 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001151 * Determines whether there is an attribute at <var>index</var>.
Alan Viverettef2969402014-10-29 17:09:36 -07001152 * <p>
1153 * <strong>Note:</strong> If the attribute was set to {@code @empty} or
1154 * {@code @undefined}, this method returns {@code false}.
Alan Viverettefd274a02014-03-27 15:39:15 -07001155 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001156 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -07001157 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001158 * @return True if the attribute has a value, false otherwise.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001159 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001160 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -07001161 public boolean hasValue(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -07001162 if (mRecycled) {
1163 throw new RuntimeException("Cannot make calls to a recycled instance!");
1164 }
1165
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001166 index *= STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001167 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001168 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001169 return type != TypedValue.TYPE_NULL;
1170 }
Alan Viverettefd274a02014-03-27 15:39:15 -07001171
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001172 /**
Alan Viverettef2969402014-10-29 17:09:36 -07001173 * Determines whether there is an attribute at <var>index</var>, returning
1174 * {@code true} if the attribute was explicitly set to {@code @empty} and
1175 * {@code false} only if the attribute was undefined.
1176 *
1177 * @param index Index of attribute to retrieve.
1178 *
1179 * @return True if the attribute has a value or is empty, false otherwise.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001180 * @throws RuntimeException if the TypedArray has already been recycled.
Alan Viverettef2969402014-10-29 17:09:36 -07001181 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -07001182 public boolean hasValueOrEmpty(@StyleableRes int index) {
Alan Viverettef2969402014-10-29 17:09:36 -07001183 if (mRecycled) {
1184 throw new RuntimeException("Cannot make calls to a recycled instance!");
1185 }
1186
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001187 index *= STYLE_NUM_ENTRIES;
Alan Viverettef2969402014-10-29 17:09:36 -07001188 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001189 final int type = data[index + STYLE_TYPE];
Alan Viverettef2969402014-10-29 17:09:36 -07001190 return type != TypedValue.TYPE_NULL
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001191 || data[index + STYLE_DATA] == TypedValue.DATA_NULL_EMPTY;
Alan Viverettef2969402014-10-29 17:09:36 -07001192 }
1193
1194 /**
Alan Viverettefd274a02014-03-27 15:39:15 -07001195 * Retrieve the raw TypedValue for the attribute at <var>index</var>
1196 * and return a temporary object holding its data. This object is only
1197 * valid until the next call on to {@link TypedArray}.
1198 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001199 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -07001200 *
1201 * @return Returns a TypedValue object if the attribute is defined,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001202 * containing its data; otherwise returns null. (You will not
1203 * receive a TypedValue whose type is TYPE_NULL.)
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001204 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001205 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -07001206 public TypedValue peekValue(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -07001207 if (mRecycled) {
1208 throw new RuntimeException("Cannot make calls to a recycled instance!");
1209 }
1210
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001211 final TypedValue value = mValue;
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001212 if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001213 return value;
1214 }
1215 return null;
1216 }
1217
1218 /**
1219 * Returns a message about the parser state suitable for printing error messages.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001220 *
1221 * @return Human-readable description of current parser state.
1222 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001223 */
1224 public String getPositionDescription() {
Alan Viverettefd274a02014-03-27 15:39:15 -07001225 if (mRecycled) {
1226 throw new RuntimeException("Cannot make calls to a recycled instance!");
1227 }
1228
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001229 return mXml != null ? mXml.getPositionDescription() : "<internal>";
1230 }
1231
1232 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001233 * Recycles the TypedArray, to be re-used by a later caller. After calling
Alan Viverettefd274a02014-03-27 15:39:15 -07001234 * this function you must not ever touch the typed array again.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001235 *
1236 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001237 */
1238 public void recycle() {
Alan Viverettefd274a02014-03-27 15:39:15 -07001239 if (mRecycled) {
1240 throw new RuntimeException(toString() + " recycled twice!");
1241 }
1242
1243 mRecycled = true;
Alan Viverette8eea3ea2014-02-03 18:40:20 -08001244
Alan Viverette52b999f2014-03-24 18:00:26 -07001245 // These may have been set by the client.
Alan Viverette8eea3ea2014-02-03 18:40:20 -08001246 mXml = null;
Alan Viverette8eea3ea2014-02-03 18:40:20 -08001247 mTheme = null;
Adam Lesinskie60064a2016-07-13 12:09:24 -07001248 mAssets = null;
Alan Viverette52b999f2014-03-24 18:00:26 -07001249
Alan Viverette8b5b25b2014-09-13 19:30:11 -07001250 mResources.mTypedArrayPool.release(this);
Alan Viverette52b999f2014-03-24 18:00:26 -07001251 }
1252
1253 /**
1254 * Extracts theme attributes from a typed array for later resolution using
Alan Viverette9cd14fc2014-06-20 14:45:11 -07001255 * {@link android.content.res.Resources.Theme#resolveAttributes(int[], int[])}.
1256 * Removes the entries from the typed array so that subsequent calls to typed
1257 * getters will return the default value without crashing.
Alan Viverette52b999f2014-03-24 18:00:26 -07001258 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001259 * @return an array of length {@link #getIndexCount()} populated with theme
1260 * attributes, or null if there are no theme attributes in the typed
1261 * array
1262 * @throws RuntimeException if the TypedArray has already been recycled.
Alan Viverette52b999f2014-03-24 18:00:26 -07001263 * @hide
1264 */
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001265 @Nullable
Mathew Inwood5c0d3542018-08-14 13:54:31 +01001266 @UnsupportedAppUsage
Alan Viverette52b999f2014-03-24 18:00:26 -07001267 public int[] extractThemeAttrs() {
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001268 return extractThemeAttrs(null);
1269 }
1270
1271 /**
1272 * @hide
1273 */
1274 @Nullable
Mathew Inwood5c0d3542018-08-14 13:54:31 +01001275 @UnsupportedAppUsage
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001276 public int[] extractThemeAttrs(@Nullable int[] scrap) {
Alan Viverettefd274a02014-03-27 15:39:15 -07001277 if (mRecycled) {
1278 throw new RuntimeException("Cannot make calls to a recycled instance!");
1279 }
1280
Alan Viverette52b999f2014-03-24 18:00:26 -07001281 int[] attrs = null;
1282
Alan Viverette0cfb8772014-05-14 17:40:53 -07001283 final int[] data = mData;
Alan Viverette1cd46122014-03-25 17:58:50 -07001284 final int N = length();
Alan Viverette52b999f2014-03-24 18:00:26 -07001285 for (int i = 0; i < N; i++) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001286 final int index = i * STYLE_NUM_ENTRIES;
1287 if (data[index + STYLE_TYPE] != TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001288 // Not an attribute, ignore.
Alan Viverette0cfb8772014-05-14 17:40:53 -07001289 continue;
Alan Viverette52b999f2014-03-24 18:00:26 -07001290 }
Alan Viverette0cfb8772014-05-14 17:40:53 -07001291
1292 // Null the entry so that we can safely call getZzz().
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001293 data[index + STYLE_TYPE] = TypedValue.TYPE_NULL;
Alan Viverette0cfb8772014-05-14 17:40:53 -07001294
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001295 final int attr = data[index + STYLE_DATA];
Alan Viverette0cfb8772014-05-14 17:40:53 -07001296 if (attr == 0) {
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001297 // Useless data, ignore.
Alan Viverette0cfb8772014-05-14 17:40:53 -07001298 continue;
1299 }
1300
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001301 // Ensure we have a usable attribute array.
Alan Viverette0cfb8772014-05-14 17:40:53 -07001302 if (attrs == null) {
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001303 if (scrap != null && scrap.length == N) {
1304 attrs = scrap;
1305 Arrays.fill(attrs, 0);
1306 } else {
1307 attrs = new int[N];
1308 }
Alan Viverette0cfb8772014-05-14 17:40:53 -07001309 }
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001310
Alan Viverette0cfb8772014-05-14 17:40:53 -07001311 attrs[i] = attr;
Alan Viverette52b999f2014-03-24 18:00:26 -07001312 }
1313
1314 return attrs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001315 }
1316
Alan Viverette8e5e11b2014-07-07 14:06:15 -07001317 /**
1318 * Return a mask of the configuration parameters for which the values in
1319 * this typed array may change.
1320 *
1321 * @return Returns a mask of the changing configuration parameters, as
1322 * defined by {@link android.content.pm.ActivityInfo}.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001323 * @throws RuntimeException if the TypedArray has already been recycled.
Alan Viverette8e5e11b2014-07-07 14:06:15 -07001324 * @see android.content.pm.ActivityInfo
1325 */
Alan Viveretteac85f902016-03-11 15:15:51 -05001326 public @Config int getChangingConfigurations() {
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001327 if (mRecycled) {
1328 throw new RuntimeException("Cannot make calls to a recycled instance!");
1329 }
1330
Alan Viveretteac85f902016-03-11 15:15:51 -05001331 @Config int changingConfig = 0;
Alan Viverette8e5e11b2014-07-07 14:06:15 -07001332
1333 final int[] data = mData;
1334 final int N = length();
1335 for (int i = 0; i < N; i++) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001336 final int index = i * STYLE_NUM_ENTRIES;
1337 final int type = data[index + STYLE_TYPE];
Alan Viverette8e5e11b2014-07-07 14:06:15 -07001338 if (type == TypedValue.TYPE_NULL) {
1339 continue;
1340 }
Alan Viveretteac85f902016-03-11 15:15:51 -05001341 changingConfig |= ActivityInfo.activityInfoConfigNativeToJava(
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001342 data[index + STYLE_CHANGING_CONFIGURATIONS]);
Alan Viverette8e5e11b2014-07-07 14:06:15 -07001343 }
1344 return changingConfig;
1345 }
1346
Mathew Inwood5c0d3542018-08-14 13:54:31 +01001347 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001348 private boolean getValueAt(int index, TypedValue outValue) {
1349 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001350 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001351 if (type == TypedValue.TYPE_NULL) {
1352 return false;
1353 }
1354 outValue.type = type;
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001355 outValue.data = data[index + STYLE_DATA];
1356 outValue.assetCookie = data[index + STYLE_ASSET_COOKIE];
1357 outValue.resourceId = data[index + STYLE_RESOURCE_ID];
Alan Viveretteac85f902016-03-11 15:15:51 -05001358 outValue.changingConfigurations = ActivityInfo.activityInfoConfigNativeToJava(
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001359 data[index + STYLE_CHANGING_CONFIGURATIONS]);
1360 outValue.density = data[index + STYLE_DENSITY];
Gilles Debunne75399682010-08-19 11:26:14 -07001361 outValue.string = (type == TypedValue.TYPE_STRING) ? loadStringValueAt(index) : null;
Aurimas Liutikasf9dbd5f2019-03-07 11:21:51 -08001362 outValue.sourceResourceId = data[index + STYLE_SOURCE_RESOURCE_ID];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001363 return true;
1364 }
1365
1366 private CharSequence loadStringValueAt(int index) {
1367 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001368 final int cookie = data[index + STYLE_ASSET_COOKIE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001369 if (cookie < 0) {
1370 if (mXml != null) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001371 return mXml.getPooledString(data[index + STYLE_DATA]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001372 }
1373 return null;
1374 }
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001375 return mAssets.getPooledStringForCookie(cookie, data[index + STYLE_DATA]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001376 }
1377
John Reckf32adf42016-11-23 10:39:40 -08001378 /** @hide */
1379 protected TypedArray(Resources resources) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001380 mResources = resources;
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001381 mMetrics = mResources.getDisplayMetrics();
1382 mAssets = mResources.getAssets();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001383 }
1384
Alan Viverette562a6a82014-01-31 11:07:29 -08001385 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001386 public String toString() {
1387 return Arrays.toString(mData);
1388 }
Kenny Root15a4d2f2010-03-11 18:20:12 -08001389}