blob: f33c75168a5f100d2e0d12e231ee328f239109f2 [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;
Alan Viveretteac85f902016-03-11 15:15:51 -050023import android.content.pm.ActivityInfo;
24import android.content.pm.ActivityInfo.Config;
Clara Bayarried00bfd2017-01-20 14:58:21 +000025import android.graphics.Typeface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import android.graphics.drawable.Drawable;
Alan Viverette6bbb47b2015-01-05 18:12:44 -080027import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import android.util.AttributeSet;
29import android.util.DisplayMetrics;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.util.TypedValue;
Dianne Hackborn2269d1572010-02-24 19:54:22 -080031
32import com.android.internal.util.XmlUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033
John Reckf32adf42016-11-23 10:39:40 -080034import dalvik.system.VMRuntime;
35
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import java.util.Arrays;
37
38/**
39 * Container for an array of values that were retrieved with
40 * {@link Resources.Theme#obtainStyledAttributes(AttributeSet, int[], int, int)}
41 * or {@link Resources#obtainAttributes}. Be
42 * sure to call {@link #recycle} when done with them.
Alan Viverettefd274a02014-03-27 15:39:15 -070043 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044 * The indices used to retrieve values from this structure correspond to
45 * the positions of the attributes given to obtainStyledAttributes.
46 */
47public class TypedArray {
Alan Viverette52b999f2014-03-24 18:00:26 -070048
49 static TypedArray obtain(Resources res, int len) {
John Reckf32adf42016-11-23 10:39:40 -080050 TypedArray attrs = res.mTypedArrayPool.acquire();
51 if (attrs == null) {
52 attrs = new TypedArray(res);
Alan Viverette52b999f2014-03-24 18:00:26 -070053 }
54
John Reckf32adf42016-11-23 10:39:40 -080055 attrs.mRecycled = false;
56 // Reset the assets, which may have changed due to configuration changes
57 // or further resource loading.
58 attrs.mAssets = res.getAssets();
Adam Lesinskiec05bc02017-04-18 14:42:22 -070059 attrs.mMetrics = res.getDisplayMetrics();
John Reckf32adf42016-11-23 10:39:40 -080060 attrs.resize(len);
61 return attrs;
Alan Viverette52b999f2014-03-24 18:00:26 -070062 }
63
Alan Viverette8b5b25b2014-09-13 19:30:11 -070064 private final Resources mResources;
Adam Lesinskiec05bc02017-04-18 14:42:22 -070065 private DisplayMetrics mMetrics;
Adam Lesinskie60064a2016-07-13 12:09:24 -070066 private AssetManager mAssets;
Alan Viverette8b5b25b2014-09-13 19:30:11 -070067
Alan Viverettefd274a02014-03-27 15:39:15 -070068 private boolean mRecycled;
69
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070 /*package*/ XmlBlock.Parser mXml;
Alan Viverette52b999f2014-03-24 18:00:26 -070071 /*package*/ Resources.Theme mTheme;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072 /*package*/ int[] mData;
John Reckf32adf42016-11-23 10:39:40 -080073 /*package*/ long mDataAddress;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074 /*package*/ int[] mIndices;
John Reckf32adf42016-11-23 10:39:40 -080075 /*package*/ long mIndicesAddress;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076 /*package*/ int mLength;
Xavier Ducrohet7f9f99ea2011-08-11 10:16:17 -070077 /*package*/ TypedValue mValue = new TypedValue();
Alan Viverette8eea3ea2014-02-03 18:40:20 -080078
John Reckf32adf42016-11-23 10:39:40 -080079 private void resize(int len) {
80 mLength = len;
Adam Lesinski7fb38312018-01-23 03:17:26 -080081 final int dataLen = len * AssetManager.STYLE_NUM_ENTRIES;
John Reckf32adf42016-11-23 10:39:40 -080082 final int indicesLen = len + 1;
83 final VMRuntime runtime = VMRuntime.getRuntime();
John Reckabd917d2017-01-04 19:04:25 -080084 if (mDataAddress == 0 || mData.length < dataLen) {
John Reckf32adf42016-11-23 10:39:40 -080085 mData = (int[]) runtime.newNonMovableArray(int.class, dataLen);
86 mDataAddress = runtime.addressOf(mData);
87 mIndices = (int[]) runtime.newNonMovableArray(int.class, indicesLen);
88 mIndicesAddress = runtime.addressOf(mIndices);
89 }
90 }
91
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -080093 * Returns the number of values in this array.
94 *
95 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096 */
97 public int length() {
Alan Viverettefd274a02014-03-27 15:39:15 -070098 if (mRecycled) {
99 throw new RuntimeException("Cannot make calls to a recycled instance!");
100 }
101
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102 return mLength;
103 }
Alan Viverettefd274a02014-03-27 15:39:15 -0700104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 /**
Adam Lesinski32e75012017-05-09 15:25:37 -0700106 * Returns the number of indices in the array that actually have data. Attributes with a value
107 * of @empty are included, as this is an explicit indicator.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800108 *
109 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110 */
111 public int getIndexCount() {
Alan Viverettefd274a02014-03-27 15:39:15 -0700112 if (mRecycled) {
113 throw new RuntimeException("Cannot make calls to a recycled instance!");
114 }
115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 return mIndices[0];
117 }
Alan Viverettefd274a02014-03-27 15:39:15 -0700118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119 /**
Adam Lesinski32e75012017-05-09 15:25:37 -0700120 * Returns an index in the array that has data. Attributes with a value of @empty are included,
121 * as this is an explicit indicator.
Alan Viverettefd274a02014-03-27 15:39:15 -0700122 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123 * @param at The index you would like to returned, ranging from 0 to
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800124 * {@link #getIndexCount()}.
Alan Viverettefd274a02014-03-27 15:39:15 -0700125 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126 * @return The index at the given offset, which can be used with
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800127 * {@link #getValue} and related APIs.
128 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129 */
130 public int getIndex(int at) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700131 if (mRecycled) {
132 throw new RuntimeException("Cannot make calls to a recycled instance!");
133 }
134
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135 return mIndices[1+at];
136 }
Alan Viverettefd274a02014-03-27 15:39:15 -0700137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800139 * Returns the Resources object this array was loaded from.
140 *
141 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 */
143 public Resources getResources() {
Alan Viverettefd274a02014-03-27 15:39:15 -0700144 if (mRecycled) {
145 throw new RuntimeException("Cannot make calls to a recycled instance!");
146 }
147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148 return mResources;
149 }
Alan Viverettefd274a02014-03-27 15:39:15 -0700150
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800152 * Retrieves the styled string value for the attribute at <var>index</var>.
153 * <p>
154 * If the attribute is not a string, this method will attempt to coerce
155 * it to a string.
Alan Viverettefd274a02014-03-27 15:39:15 -0700156 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -0700158 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800159 * @return CharSequence holding string data. May be styled. Returns
160 * {@code null} if the attribute is not defined or could not be
161 * coerced to a string.
162 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700164 public CharSequence getText(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700165 if (mRecycled) {
166 throw new RuntimeException("Cannot make calls to a recycled instance!");
167 }
168
Adam Lesinski7fb38312018-01-23 03:17:26 -0800169 index *= AssetManager.STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 final int[] data = mData;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800171 final int type = data[index+AssetManager.STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 if (type == TypedValue.TYPE_NULL) {
173 return null;
174 } else if (type == TypedValue.TYPE_STRING) {
175 return loadStringValueAt(index);
176 }
177
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800178 final TypedValue v = mValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179 if (getValueAt(index, v)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800180 return v.coerceToString();
181 }
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800182
183 // We already checked for TYPE_NULL. This should never happen.
184 throw new RuntimeException("getText of bad type: 0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185 }
186
187 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800188 * Retrieves the string value for the attribute at <var>index</var>.
189 * <p>
190 * If the attribute is not a string, this method will attempt to coerce
191 * it to a string.
Alan Viverettefd274a02014-03-27 15:39:15 -0700192 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -0700194 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800195 * @return String holding string data. Any styling information is removed.
196 * Returns {@code null} if the attribute is not defined or could
197 * not be coerced to a string.
198 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199 */
Alan Viverettea6f354b2015-05-18 15:26:57 -0700200 @Nullable
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700201 public String getString(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700202 if (mRecycled) {
203 throw new RuntimeException("Cannot make calls to a recycled instance!");
204 }
205
Adam Lesinski7fb38312018-01-23 03:17:26 -0800206 index *= AssetManager.STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 final int[] data = mData;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800208 final int type = data[index+AssetManager.STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 if (type == TypedValue.TYPE_NULL) {
210 return null;
211 } else if (type == TypedValue.TYPE_STRING) {
212 return loadStringValueAt(index).toString();
213 }
214
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800215 final TypedValue v = mValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 if (getValueAt(index, v)) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800217 final CharSequence cs = v.coerceToString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218 return cs != null ? cs.toString() : null;
219 }
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800220
221 // We already checked for TYPE_NULL. This should never happen.
222 throw new RuntimeException("getString of bad type: 0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223 }
224
225 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800226 * Retrieves the string value for the attribute at <var>index</var>, but
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227 * only if that string comes from an immediate value in an XML file. That
228 * is, this does not allow references to string resources, string
229 * attributes, or conversions from other types. As such, this method
230 * will only return strings for TypedArray objects that come from
231 * attributes in an XML file.
Alan Viverettefd274a02014-03-27 15:39:15 -0700232 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800233 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -0700234 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800235 * @return String holding string data. Any styling information is removed.
236 * Returns {@code null} if the attribute is not defined or is not
237 * an immediate string value.
238 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700240 public String getNonResourceString(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700241 if (mRecycled) {
242 throw new RuntimeException("Cannot make calls to a recycled instance!");
243 }
244
Adam Lesinski7fb38312018-01-23 03:17:26 -0800245 index *= AssetManager.STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246 final int[] data = mData;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800247 final int type = data[index+AssetManager.STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248 if (type == TypedValue.TYPE_STRING) {
Adam Lesinski7fb38312018-01-23 03:17:26 -0800249 final int cookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250 if (cookie < 0) {
Adam Lesinski7fb38312018-01-23 03:17:26 -0800251 return mXml.getPooledString(
252 data[index+AssetManager.STYLE_DATA]).toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 }
254 }
255 return null;
256 }
Alan Viverettefd274a02014-03-27 15:39:15 -0700257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800259 * Retrieves the string value for the attribute at <var>index</var> that is
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800260 * not allowed to change with the given configurations.
Alan Viverettefd274a02014-03-27 15:39:15 -0700261 *
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800262 * @param index Index of attribute to retrieve.
263 * @param allowedChangingConfigs Bit mask of configurations from
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800264 * {@link Configuration}.NATIVE_CONFIG_* that are allowed to change.
Dianne Hackborn1d0b1772013-09-06 14:02:54 -0700265 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800266 * @return String holding string data. Any styling information is removed.
267 * Returns {@code null} if the attribute is not defined.
268 * @throws RuntimeException if the TypedArray has already been recycled.
269 * @hide
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800270 */
Alan Viveretteac85f902016-03-11 15:15:51 -0500271 public String getNonConfigurationString(@StyleableRes int index,
272 @Config int allowedChangingConfigs) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700273 if (mRecycled) {
274 throw new RuntimeException("Cannot make calls to a recycled instance!");
275 }
276
Adam Lesinski7fb38312018-01-23 03:17:26 -0800277 index *= AssetManager.STYLE_NUM_ENTRIES;
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800278 final int[] data = mData;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800279 final int type = data[index+AssetManager.STYLE_TYPE];
Alan Viveretteac85f902016-03-11 15:15:51 -0500280 final @Config int changingConfigs = ActivityInfo.activityInfoConfigNativeToJava(
Adam Lesinski7fb38312018-01-23 03:17:26 -0800281 data[index + AssetManager.STYLE_CHANGING_CONFIGURATIONS]);
Alan Viveretteac85f902016-03-11 15:15:51 -0500282 if ((changingConfigs & ~allowedChangingConfigs) != 0) {
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800283 return null;
284 }
285 if (type == TypedValue.TYPE_NULL) {
286 return null;
287 } else if (type == TypedValue.TYPE_STRING) {
288 return loadStringValueAt(index).toString();
289 }
290
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800291 final TypedValue v = mValue;
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800292 if (getValueAt(index, v)) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800293 final CharSequence cs = v.coerceToString();
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800294 return cs != null ? cs.toString() : null;
295 }
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800296
297 // We already checked for TYPE_NULL. This should never happen.
298 throw new RuntimeException("getNonConfigurationString of bad type: 0x"
299 + Integer.toHexString(type));
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800300 }
301
302 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303 * Retrieve the boolean value for the attribute at <var>index</var>.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800304 * <p>
305 * If the attribute is an integer value, this method will return whether
306 * it is equal to zero. If the attribute is not a boolean or integer value,
307 * this method will attempt to coerce it to an integer using
308 * {@link Integer#decode(String)} and return whether it is equal to zero.
Alan Viverettefd274a02014-03-27 15:39:15 -0700309 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 * @param index Index of attribute to retrieve.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800311 * @param defValue Value to return if the attribute is not defined or
312 * cannot be coerced to an integer.
Alan Viverettefd274a02014-03-27 15:39:15 -0700313 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800314 * @return Boolean value of the attribute, or defValue if the attribute was
315 * not defined or could not be coerced to an integer.
316 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700318 public boolean getBoolean(@StyleableRes int index, boolean defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700319 if (mRecycled) {
320 throw new RuntimeException("Cannot make calls to a recycled instance!");
321 }
322
Adam Lesinski7fb38312018-01-23 03:17:26 -0800323 index *= AssetManager.STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800324 final int[] data = mData;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800325 final int type = data[index+AssetManager.STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326 if (type == TypedValue.TYPE_NULL) {
327 return defValue;
328 } else if (type >= TypedValue.TYPE_FIRST_INT
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800329 && type <= TypedValue.TYPE_LAST_INT) {
Adam Lesinski7fb38312018-01-23 03:17:26 -0800330 return data[index+AssetManager.STYLE_DATA] != 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331 }
332
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800333 final TypedValue v = mValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334 if (getValueAt(index, v)) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800335 StrictMode.noteResourceMismatch(v);
336 return XmlUtils.convertValueToBoolean(v.coerceToString(), defValue);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 }
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800338
339 // We already checked for TYPE_NULL. This should never happen.
340 throw new RuntimeException("getBoolean of bad type: 0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800341 }
342
343 /**
344 * Retrieve the integer value for the attribute at <var>index</var>.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800345 * <p>
346 * If the attribute is not an integer, this method will attempt to coerce
347 * it to an integer using {@link Integer#decode(String)}.
Alan Viverettefd274a02014-03-27 15:39:15 -0700348 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 * @param index Index of attribute to retrieve.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800350 * @param defValue Value to return if the attribute is not defined or
351 * cannot be coerced to an integer.
Alan Viverettefd274a02014-03-27 15:39:15 -0700352 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800353 * @return Integer value of the attribute, or defValue if the attribute was
354 * not defined or could not be coerced to an integer.
355 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800356 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700357 public int getInt(@StyleableRes int index, int defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700358 if (mRecycled) {
359 throw new RuntimeException("Cannot make calls to a recycled instance!");
360 }
361
Adam Lesinski7fb38312018-01-23 03:17:26 -0800362 index *= AssetManager.STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 final int[] data = mData;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800364 final int type = data[index+AssetManager.STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365 if (type == TypedValue.TYPE_NULL) {
366 return defValue;
367 } else if (type >= TypedValue.TYPE_FIRST_INT
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800368 && type <= TypedValue.TYPE_LAST_INT) {
Adam Lesinski7fb38312018-01-23 03:17:26 -0800369 return data[index+AssetManager.STYLE_DATA];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370 }
371
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800372 final TypedValue v = mValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800373 if (getValueAt(index, v)) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800374 StrictMode.noteResourceMismatch(v);
375 return XmlUtils.convertValueToInt(v.coerceToString(), defValue);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 }
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800377
378 // We already checked for TYPE_NULL. This should never happen.
379 throw new RuntimeException("getInt of bad type: 0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800380 }
381
382 /**
383 * Retrieve the float value for the attribute at <var>index</var>.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800384 * <p>
385 * If the attribute is not a float or an integer, this method will attempt
386 * to coerce it to a float using {@link Float#parseFloat(String)}.
Alan Viverettefd274a02014-03-27 15:39:15 -0700387 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800388 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -0700389 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800390 * @return Attribute float value, or defValue if the attribute was
391 * not defined or could not be coerced to a float.
392 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700394 public float getFloat(@StyleableRes int index, float defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700395 if (mRecycled) {
396 throw new RuntimeException("Cannot make calls to a recycled instance!");
397 }
398
Adam Lesinski7fb38312018-01-23 03:17:26 -0800399 index *= AssetManager.STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 final int[] data = mData;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800401 final int type = data[index+AssetManager.STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 if (type == TypedValue.TYPE_NULL) {
403 return defValue;
404 } else if (type == TypedValue.TYPE_FLOAT) {
Adam Lesinski7fb38312018-01-23 03:17:26 -0800405 return Float.intBitsToFloat(data[index+AssetManager.STYLE_DATA]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800406 } else if (type >= TypedValue.TYPE_FIRST_INT
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800407 && type <= TypedValue.TYPE_LAST_INT) {
Adam Lesinski7fb38312018-01-23 03:17:26 -0800408 return data[index+AssetManager.STYLE_DATA];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 }
410
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800411 final TypedValue v = mValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 if (getValueAt(index, v)) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800413 final CharSequence str = v.coerceToString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 if (str != null) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800415 StrictMode.noteResourceMismatch(v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 return Float.parseFloat(str.toString());
417 }
418 }
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800419
420 // We already checked for TYPE_NULL. This should never happen.
421 throw new RuntimeException("getFloat of bad type: 0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422 }
Alan Viverettefd274a02014-03-27 15:39:15 -0700423
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800424 /**
425 * Retrieve the color value for the attribute at <var>index</var>. If
426 * the attribute references a color resource holding a complex
427 * {@link android.content.res.ColorStateList}, then the default color from
428 * the set is returned.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800429 * <p>
430 * This method will throw an exception if the attribute is defined but is
431 * not an integer color or color state list.
Alan Viverettefd274a02014-03-27 15:39:15 -0700432 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800433 * @param index Index of attribute to retrieve.
434 * @param defValue Value to return if the attribute is not defined or
435 * not a resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700436 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437 * @return Attribute color value, or defValue if not defined.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800438 * @throws RuntimeException if the TypedArray has already been recycled.
439 * @throws UnsupportedOperationException if the attribute is defined but is
440 * not an integer color or color state list.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 */
Tor Norbye80756e32015-03-02 09:39:27 -0800442 @ColorInt
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700443 public int getColor(@StyleableRes int index, @ColorInt int defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700444 if (mRecycled) {
445 throw new RuntimeException("Cannot make calls to a recycled instance!");
446 }
447
Alan Viverette5b90e822016-02-24 09:06:47 -0500448 final int attrIndex = index;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800449 index *= AssetManager.STYLE_NUM_ENTRIES;
Alan Viverette5b90e822016-02-24 09:06:47 -0500450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 final int[] data = mData;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800452 final int type = data[index+AssetManager.STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800453 if (type == TypedValue.TYPE_NULL) {
454 return defValue;
455 } else if (type >= TypedValue.TYPE_FIRST_INT
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800456 && type <= TypedValue.TYPE_LAST_INT) {
Adam Lesinski7fb38312018-01-23 03:17:26 -0800457 return data[index+AssetManager.STYLE_DATA];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458 } else if (type == TypedValue.TYPE_STRING) {
459 final TypedValue value = mValue;
460 if (getValueAt(index, value)) {
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800461 final ColorStateList csl = mResources.loadColorStateList(
462 value, value.resourceId, mTheme);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800463 return csl.getDefaultColor();
464 }
465 return defValue;
Alan Viverette216d3e62014-07-29 10:35:42 -0700466 } else if (type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette93795052015-03-09 15:32:50 -0700467 final TypedValue value = mValue;
Alan Viverette5b90e822016-02-24 09:06:47 -0500468 getValueAt(index, value);
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800469 throw new UnsupportedOperationException(
Alan Viverette5b90e822016-02-24 09:06:47 -0500470 "Failed to resolve attribute at index " + attrIndex + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 }
472
Alan Viverette5b90e822016-02-24 09:06:47 -0500473 throw new UnsupportedOperationException("Can't convert value at index " + attrIndex
474 + " to color: type=0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800475 }
476
477 /**
Teng-Hui Zhudbee9bb2015-12-15 11:01:27 -0800478 * Retrieve the ComplexColor for the attribute at <var>index</var>.
479 * The value may be either a {@link android.content.res.ColorStateList} which can wrap a simple
480 * color value or a {@link android.content.res.GradientColor}
481 * <p>
482 * This method will return {@code null} if the attribute is not defined or
483 * is not an integer color, color state list or GradientColor.
484 *
485 * @param index Index of attribute to retrieve.
486 *
487 * @return ComplexColor for the attribute, or {@code null} if not defined.
488 * @throws RuntimeException if the attribute if the TypedArray has already
489 * been recycled.
490 * @throws UnsupportedOperationException if the attribute is defined but is
491 * not an integer color, color state list or GradientColor.
Teng-Hui Zhue03c4692016-03-17 10:38:43 -0700492 * @hide
Teng-Hui Zhudbee9bb2015-12-15 11:01:27 -0800493 */
494 @Nullable
495 public ComplexColor getComplexColor(@StyleableRes int index) {
496 if (mRecycled) {
497 throw new RuntimeException("Cannot make calls to a recycled instance!");
498 }
499
500 final TypedValue value = mValue;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800501 if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
Teng-Hui Zhudbee9bb2015-12-15 11:01:27 -0800502 if (value.type == TypedValue.TYPE_ATTRIBUTE) {
503 throw new UnsupportedOperationException(
504 "Failed to resolve attribute at index " + index + ": " + value);
505 }
506 return mResources.loadComplexColor(value, value.resourceId, mTheme);
507 }
508 return null;
509 }
510
511 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512 * Retrieve the ColorStateList for the attribute at <var>index</var>.
513 * The value may be either a single solid color or a reference to
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800514 * a color or complex {@link android.content.res.ColorStateList}
515 * description.
516 * <p>
517 * This method will return {@code null} if the attribute is not defined or
518 * is not an integer color or color state list.
Alan Viverettefd274a02014-03-27 15:39:15 -0700519 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -0700521 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800522 * @return ColorStateList for the attribute, or {@code null} if not
523 * defined.
524 * @throws RuntimeException if the attribute if the TypedArray has already
525 * been recycled.
526 * @throws UnsupportedOperationException if the attribute is defined but is
527 * not an integer color or color state list.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800528 */
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800529 @Nullable
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700530 public ColorStateList getColorStateList(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700531 if (mRecycled) {
532 throw new RuntimeException("Cannot make calls to a recycled instance!");
533 }
534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535 final TypedValue value = mValue;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800536 if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
Alan Viverette216d3e62014-07-29 10:35:42 -0700537 if (value.type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800538 throw new UnsupportedOperationException(
Alan Viverette93795052015-03-09 15:32:50 -0700539 "Failed to resolve attribute at index " + index + ": " + value);
Alan Viverette216d3e62014-07-29 10:35:42 -0700540 }
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800541 return mResources.loadColorStateList(value, value.resourceId, mTheme);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542 }
543 return null;
544 }
545
546 /**
547 * Retrieve the integer value for the attribute at <var>index</var>.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800548 * <p>
549 * Unlike {@link #getInt(int, int)}, this method will throw an exception if
550 * the attribute is defined but is not an integer.
Alan Viverettefd274a02014-03-27 15:39:15 -0700551 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800552 * @param index Index of attribute to retrieve.
553 * @param defValue Value to return if the attribute is not defined or
554 * not a resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700555 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 * @return Attribute integer value, or defValue if not defined.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800557 * @throws RuntimeException if the TypedArray has already been recycled.
558 * @throws UnsupportedOperationException if the attribute is defined but is
559 * not an integer.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800560 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700561 public int getInteger(@StyleableRes int index, int defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700562 if (mRecycled) {
563 throw new RuntimeException("Cannot make calls to a recycled instance!");
564 }
565
Alan Viverette5b90e822016-02-24 09:06:47 -0500566 final int attrIndex = index;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800567 index *= AssetManager.STYLE_NUM_ENTRIES;
Alan Viverette5b90e822016-02-24 09:06:47 -0500568
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800569 final int[] data = mData;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800570 final int type = data[index+AssetManager.STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800571 if (type == TypedValue.TYPE_NULL) {
572 return defValue;
573 } else if (type >= TypedValue.TYPE_FIRST_INT
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800574 && type <= TypedValue.TYPE_LAST_INT) {
Adam Lesinski7fb38312018-01-23 03:17:26 -0800575 return data[index+AssetManager.STYLE_DATA];
Alan Viverette216d3e62014-07-29 10:35:42 -0700576 } else if (type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette93795052015-03-09 15:32:50 -0700577 final TypedValue value = mValue;
Alan Viverette5b90e822016-02-24 09:06:47 -0500578 getValueAt(index, value);
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800579 throw new UnsupportedOperationException(
Alan Viverette5b90e822016-02-24 09:06:47 -0500580 "Failed to resolve attribute at index " + attrIndex + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800581 }
582
Alan Viverette5b90e822016-02-24 09:06:47 -0500583 throw new UnsupportedOperationException("Can't convert value at index " + attrIndex
584 + " to integer: type=0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585 }
586
587 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800588 * Retrieve a dimensional unit attribute at <var>index</var>. Unit
Alan Viverettefd274a02014-03-27 15:39:15 -0700589 * conversions are based on the current {@link DisplayMetrics}
590 * associated with the resources this {@link TypedArray} object
591 * came from.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800592 * <p>
593 * This method will throw an exception if the attribute is defined but is
594 * not a dimension.
Alan Viverettefd274a02014-03-27 15:39:15 -0700595 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800596 * @param index Index of attribute to retrieve.
597 * @param defValue Value to return if the attribute is not defined or
598 * not a resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700599 *
600 * @return Attribute dimension value multiplied by the appropriate
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800601 * metric, or defValue if not defined.
602 * @throws RuntimeException if the TypedArray has already been recycled.
603 * @throws UnsupportedOperationException if the attribute is defined but is
604 * not an integer.
Alan Viverettefd274a02014-03-27 15:39:15 -0700605 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800606 * @see #getDimensionPixelOffset
607 * @see #getDimensionPixelSize
608 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700609 public float getDimension(@StyleableRes int index, float defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700610 if (mRecycled) {
611 throw new RuntimeException("Cannot make calls to a recycled instance!");
612 }
613
Alan Viverette5b90e822016-02-24 09:06:47 -0500614 final int attrIndex = index;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800615 index *= AssetManager.STYLE_NUM_ENTRIES;
Alan Viverette5b90e822016-02-24 09:06:47 -0500616
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800617 final int[] data = mData;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800618 final int type = data[index+AssetManager.STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800619 if (type == TypedValue.TYPE_NULL) {
620 return defValue;
621 } else if (type == TypedValue.TYPE_DIMENSION) {
Adam Lesinski7fb38312018-01-23 03:17:26 -0800622 return TypedValue.complexToDimension(
623 data[index + AssetManager.STYLE_DATA], mMetrics);
Alan Viverette216d3e62014-07-29 10:35:42 -0700624 } else if (type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette93795052015-03-09 15:32:50 -0700625 final TypedValue value = mValue;
Alan Viverette5b90e822016-02-24 09:06:47 -0500626 getValueAt(index, value);
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800627 throw new UnsupportedOperationException(
Alan Viverette5b90e822016-02-24 09:06:47 -0500628 "Failed to resolve attribute at index " + attrIndex + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629 }
630
Alan Viverette5b90e822016-02-24 09:06:47 -0500631 throw new UnsupportedOperationException("Can't convert value at index " + attrIndex
632 + " to dimension: type=0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800633 }
634
635 /**
636 * Retrieve a dimensional unit attribute at <var>index</var> for use
637 * as an offset in raw pixels. This is the same as
638 * {@link #getDimension}, except the returned value is converted to
639 * integer pixels for you. An offset conversion involves simply
640 * truncating the base value to an integer.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800641 * <p>
642 * This method will throw an exception if the attribute is defined but is
643 * not a dimension.
Alan Viverettefd274a02014-03-27 15:39:15 -0700644 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800645 * @param index Index of attribute to retrieve.
646 * @param defValue Value to return if the attribute is not defined or
647 * not a resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700648 *
649 * @return Attribute dimension value multiplied by the appropriate
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800650 * metric and truncated to integer pixels, or defValue if not defined.
651 * @throws RuntimeException if the TypedArray has already been recycled.
652 * @throws UnsupportedOperationException if the attribute is defined but is
653 * not an integer.
Alan Viverettefd274a02014-03-27 15:39:15 -0700654 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800655 * @see #getDimension
656 * @see #getDimensionPixelSize
657 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700658 public int getDimensionPixelOffset(@StyleableRes int index, int defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700659 if (mRecycled) {
660 throw new RuntimeException("Cannot make calls to a recycled instance!");
661 }
662
Alan Viverette5b90e822016-02-24 09:06:47 -0500663 final int attrIndex = index;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800664 index *= AssetManager.STYLE_NUM_ENTRIES;
Alan Viverette5b90e822016-02-24 09:06:47 -0500665
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800666 final int[] data = mData;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800667 final int type = data[index+AssetManager.STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668 if (type == TypedValue.TYPE_NULL) {
669 return defValue;
670 } else if (type == TypedValue.TYPE_DIMENSION) {
Adam Lesinski7fb38312018-01-23 03:17:26 -0800671 return TypedValue.complexToDimensionPixelOffset(
672 data[index + AssetManager.STYLE_DATA], mMetrics);
Alan Viverette216d3e62014-07-29 10:35:42 -0700673 } else if (type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette93795052015-03-09 15:32:50 -0700674 final TypedValue value = mValue;
Alan Viverette5b90e822016-02-24 09:06:47 -0500675 getValueAt(index, value);
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800676 throw new UnsupportedOperationException(
Alan Viverette5b90e822016-02-24 09:06:47 -0500677 "Failed to resolve attribute at index " + attrIndex + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800678 }
679
Alan Viverette5b90e822016-02-24 09:06:47 -0500680 throw new UnsupportedOperationException("Can't convert value at index " + attrIndex
681 + " to dimension: type=0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800682 }
683
684 /**
685 * Retrieve a dimensional unit attribute at <var>index</var> for use
686 * as a size in raw pixels. This is the same as
687 * {@link #getDimension}, except the returned value is converted to
688 * integer pixels for use as a size. A size conversion involves
689 * rounding the base value, and ensuring that a non-zero base value
690 * is at least one pixel in size.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800691 * <p>
692 * This method will throw an exception if the attribute is defined but is
693 * not a dimension.
Alan Viverettefd274a02014-03-27 15:39:15 -0700694 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800695 * @param index Index of attribute to retrieve.
696 * @param defValue Value to return if the attribute is not defined or
697 * not a resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700698 *
699 * @return Attribute dimension value multiplied by the appropriate
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800700 * metric and truncated to integer pixels, or defValue if not defined.
701 * @throws RuntimeException if the TypedArray has already been recycled.
702 * @throws UnsupportedOperationException if the attribute is defined but is
703 * not a dimension.
Alan Viverettefd274a02014-03-27 15:39:15 -0700704 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800705 * @see #getDimension
706 * @see #getDimensionPixelOffset
707 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700708 public int getDimensionPixelSize(@StyleableRes int index, int defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700709 if (mRecycled) {
710 throw new RuntimeException("Cannot make calls to a recycled instance!");
711 }
712
Alan Viverette5b90e822016-02-24 09:06:47 -0500713 final int attrIndex = index;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800714 index *= AssetManager.STYLE_NUM_ENTRIES;
Alan Viverette5b90e822016-02-24 09:06:47 -0500715
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800716 final int[] data = mData;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800717 final int type = data[index+AssetManager.STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800718 if (type == TypedValue.TYPE_NULL) {
719 return defValue;
720 } else if (type == TypedValue.TYPE_DIMENSION) {
Adam Lesinski7fb38312018-01-23 03:17:26 -0800721 return TypedValue.complexToDimensionPixelSize(
722 data[index+AssetManager.STYLE_DATA], mMetrics);
Alan Viverette216d3e62014-07-29 10:35:42 -0700723 } else if (type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette93795052015-03-09 15:32:50 -0700724 final TypedValue value = mValue;
Alan Viverette5b90e822016-02-24 09:06:47 -0500725 getValueAt(index, value);
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800726 throw new UnsupportedOperationException(
Alan Viverette5b90e822016-02-24 09:06:47 -0500727 "Failed to resolve attribute at index " + attrIndex + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800728 }
729
Alan Viverette5b90e822016-02-24 09:06:47 -0500730 throw new UnsupportedOperationException("Can't convert value at index " + attrIndex
731 + " to dimension: type=0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800732 }
733
734 /**
735 * Special version of {@link #getDimensionPixelSize} for retrieving
736 * {@link android.view.ViewGroup}'s layout_width and layout_height
737 * attributes. This is only here for performance reasons; applications
738 * should use {@link #getDimensionPixelSize}.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800739 * <p>
740 * This method will throw an exception if the attribute is defined but is
741 * not a dimension or integer (enum).
Alan Viverettefd274a02014-03-27 15:39:15 -0700742 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800743 * @param index Index of the attribute to retrieve.
744 * @param name Textual name of attribute for error reporting.
Alan Viverettefd274a02014-03-27 15:39:15 -0700745 *
746 * @return Attribute dimension value multiplied by the appropriate
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800747 * metric and truncated to integer pixels.
748 * @throws RuntimeException if the TypedArray has already been recycled.
749 * @throws UnsupportedOperationException if the attribute is defined but is
750 * not a dimension or integer (enum).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800751 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700752 public int getLayoutDimension(@StyleableRes int index, String name) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700753 if (mRecycled) {
754 throw new RuntimeException("Cannot make calls to a recycled instance!");
755 }
756
Alan Viverette5b90e822016-02-24 09:06:47 -0500757 final int attrIndex = index;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800758 index *= AssetManager.STYLE_NUM_ENTRIES;
Alan Viverette5b90e822016-02-24 09:06:47 -0500759
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800760 final int[] data = mData;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800761 final int type = data[index+AssetManager.STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800762 if (type >= TypedValue.TYPE_FIRST_INT
763 && type <= TypedValue.TYPE_LAST_INT) {
Adam Lesinski7fb38312018-01-23 03:17:26 -0800764 return data[index+AssetManager.STYLE_DATA];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800765 } else if (type == TypedValue.TYPE_DIMENSION) {
Adam Lesinski7fb38312018-01-23 03:17:26 -0800766 return TypedValue.complexToDimensionPixelSize(
767 data[index+AssetManager.STYLE_DATA], mMetrics);
Alan Viverette216d3e62014-07-29 10:35:42 -0700768 } else if (type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette93795052015-03-09 15:32:50 -0700769 final TypedValue value = mValue;
Alan Viverette5b90e822016-02-24 09:06:47 -0500770 getValueAt(index, value);
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800771 throw new UnsupportedOperationException(
Alan Viverette5b90e822016-02-24 09:06:47 -0500772 "Failed to resolve attribute at index " + attrIndex + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800773 }
774
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800775 throw new UnsupportedOperationException(getPositionDescription()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776 + ": You must supply a " + name + " attribute.");
777 }
Alan Viverettefd274a02014-03-27 15:39:15 -0700778
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800779 /**
780 * Special version of {@link #getDimensionPixelSize} for retrieving
781 * {@link android.view.ViewGroup}'s layout_width and layout_height
782 * attributes. This is only here for performance reasons; applications
783 * should use {@link #getDimensionPixelSize}.
Alan Viverettefd274a02014-03-27 15:39:15 -0700784 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800785 * @param index Index of the attribute to retrieve.
786 * @param defValue The default value to return if this attribute is not
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800787 * default or contains the wrong type of data.
Alan Viverettefd274a02014-03-27 15:39:15 -0700788 *
789 * @return Attribute dimension value multiplied by the appropriate
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800790 * metric and truncated to integer pixels.
791 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800792 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700793 public int getLayoutDimension(@StyleableRes int index, int defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700794 if (mRecycled) {
795 throw new RuntimeException("Cannot make calls to a recycled instance!");
796 }
797
Adam Lesinski7fb38312018-01-23 03:17:26 -0800798 index *= AssetManager.STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800799 final int[] data = mData;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800800 final int type = data[index+AssetManager.STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801 if (type >= TypedValue.TYPE_FIRST_INT
802 && type <= TypedValue.TYPE_LAST_INT) {
Adam Lesinski7fb38312018-01-23 03:17:26 -0800803 return data[index+AssetManager.STYLE_DATA];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800804 } else if (type == TypedValue.TYPE_DIMENSION) {
Adam Lesinski7fb38312018-01-23 03:17:26 -0800805 return TypedValue.complexToDimensionPixelSize(
806 data[index + AssetManager.STYLE_DATA], mMetrics);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800807 }
808
809 return defValue;
810 }
811
812 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800813 * Retrieves a fractional unit attribute at <var>index</var>.
Alan Viverettefd274a02014-03-27 15:39:15 -0700814 *
815 * @param index Index of attribute to retrieve.
816 * @param base The base value of this fraction. In other words, a
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800817 * standard fraction is multiplied by this value.
Alan Viverettefd274a02014-03-27 15:39:15 -0700818 * @param pbase The parent base value of this fraction. In other
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800819 * words, a parent fraction (nn%p) is multiplied by this
820 * value.
821 * @param defValue Value to return if the attribute is not defined or
822 * not a resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700823 *
824 * @return Attribute fractional value multiplied by the appropriate
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800825 * base value, or defValue if not defined.
826 * @throws RuntimeException if the TypedArray has already been recycled.
827 * @throws UnsupportedOperationException if the attribute is defined but is
828 * not a fraction.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700830 public float getFraction(@StyleableRes int index, int base, int pbase, float defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700831 if (mRecycled) {
832 throw new RuntimeException("Cannot make calls to a recycled instance!");
833 }
834
Alan Viverette5b90e822016-02-24 09:06:47 -0500835 final int attrIndex = index;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800836 index *= AssetManager.STYLE_NUM_ENTRIES;
Alan Viverette5b90e822016-02-24 09:06:47 -0500837
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800838 final int[] data = mData;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800839 final int type = data[index+AssetManager.STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800840 if (type == TypedValue.TYPE_NULL) {
841 return defValue;
842 } else if (type == TypedValue.TYPE_FRACTION) {
Adam Lesinski7fb38312018-01-23 03:17:26 -0800843 return TypedValue.complexToFraction(
844 data[index+AssetManager.STYLE_DATA], base, pbase);
Alan Viverette216d3e62014-07-29 10:35:42 -0700845 } else if (type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette93795052015-03-09 15:32:50 -0700846 final TypedValue value = mValue;
Alan Viverette5b90e822016-02-24 09:06:47 -0500847 getValueAt(index, value);
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800848 throw new UnsupportedOperationException(
Alan Viverette5b90e822016-02-24 09:06:47 -0500849 "Failed to resolve attribute at index " + attrIndex + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800850 }
851
Alan Viverette5b90e822016-02-24 09:06:47 -0500852 throw new UnsupportedOperationException("Can't convert value at index " + attrIndex
853 + " to fraction: type=0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800854 }
855
856 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800857 * Retrieves the resource identifier for the attribute at
Alan Viverettefd274a02014-03-27 15:39:15 -0700858 * <var>index</var>. Note that attribute resource as resolved when
859 * the overall {@link TypedArray} object is retrieved. As a
860 * result, this function will return the resource identifier of the
861 * final resource value that was found, <em>not</em> necessarily the
862 * original resource that was specified by the attribute.
863 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864 * @param index Index of attribute to retrieve.
865 * @param defValue Value to return if the attribute is not defined or
866 * not a resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700867 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800868 * @return Attribute resource identifier, or defValue if not defined.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800869 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800870 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700871 @AnyRes
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700872 public int getResourceId(@StyleableRes int index, int defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700873 if (mRecycled) {
874 throw new RuntimeException("Cannot make calls to a recycled instance!");
875 }
876
Adam Lesinski7fb38312018-01-23 03:17:26 -0800877 index *= AssetManager.STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800878 final int[] data = mData;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800879 if (data[index+AssetManager.STYLE_TYPE] != TypedValue.TYPE_NULL) {
880 final int resid = data[index+AssetManager.STYLE_RESOURCE_ID];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800881 if (resid != 0) {
882 return resid;
883 }
884 }
885 return defValue;
886 }
887
888 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800889 * Retrieves the theme attribute resource identifier for the attribute at
Alan Viverette500c5602014-07-29 11:30:35 -0700890 * <var>index</var>.
891 *
892 * @param index Index of attribute to retrieve.
893 * @param defValue Value to return if the attribute is not defined or not a
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800894 * resource.
895 *
Alan Viverette500c5602014-07-29 11:30:35 -0700896 * @return Theme attribute resource identifier, or defValue if not defined.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800897 * @throws RuntimeException if the TypedArray has already been recycled.
Alan Viverette500c5602014-07-29 11:30:35 -0700898 * @hide
899 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700900 public int getThemeAttributeId(@StyleableRes int index, int defValue) {
Alan Viverette500c5602014-07-29 11:30:35 -0700901 if (mRecycled) {
902 throw new RuntimeException("Cannot make calls to a recycled instance!");
903 }
904
Adam Lesinski7fb38312018-01-23 03:17:26 -0800905 index *= AssetManager.STYLE_NUM_ENTRIES;
Alan Viverette500c5602014-07-29 11:30:35 -0700906 final int[] data = mData;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800907 if (data[index + AssetManager.STYLE_TYPE] == TypedValue.TYPE_ATTRIBUTE) {
908 return data[index + AssetManager.STYLE_DATA];
Alan Viverette500c5602014-07-29 11:30:35 -0700909 }
910 return defValue;
911 }
912
913 /**
Alan Viverettefde4e3b2014-09-22 16:19:51 -0700914 * Retrieve the Drawable for the attribute at <var>index</var>.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800915 * <p>
916 * This method will throw an exception if the attribute is defined but is
917 * not a color or drawable resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700918 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -0700920 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800921 * @return Drawable for the attribute, or {@code null} if not defined.
922 * @throws RuntimeException if the TypedArray has already been recycled.
923 * @throws UnsupportedOperationException if the attribute is defined but is
924 * not a color or drawable resource.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800925 */
Alan Viverettefde4e3b2014-09-22 16:19:51 -0700926 @Nullable
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700927 public Drawable getDrawable(@StyleableRes int index) {
Adam Lesinski50954d22017-04-14 18:41:52 -0700928 return getDrawableForDensity(index, 0);
929 }
930
931 /**
932 * Version of {@link #getDrawable(int)} that accepts an override density.
933 * @hide
934 */
935 @Nullable
936 public Drawable getDrawableForDensity(@StyleableRes int index, int density) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700937 if (mRecycled) {
938 throw new RuntimeException("Cannot make calls to a recycled instance!");
939 }
940
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800941 final TypedValue value = mValue;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800942 if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
Alan Viverette216d3e62014-07-29 10:35:42 -0700943 if (value.type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800944 throw new UnsupportedOperationException(
Alan Viverette93795052015-03-09 15:32:50 -0700945 "Failed to resolve attribute at index " + index + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800946 }
Adam Lesinski50954d22017-04-14 18:41:52 -0700947
948 if (density > 0) {
949 // If the density is overridden, the value in the TypedArray will not reflect this.
950 // Do a separate lookup of the resourceId with the density override.
951 mResources.getValueForDensity(value.resourceId, density, value, true);
952 }
953 return mResources.loadDrawable(value, value.resourceId, density, mTheme);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800954 }
955 return null;
956 }
957
958 /**
Clara Bayarried00bfd2017-01-20 14:58:21 +0000959 * Retrieve the Typeface for the attribute at <var>index</var>.
960 * <p>
961 * This method will throw an exception if the attribute is defined but is
962 * not a font.
963 *
964 * @param index Index of attribute to retrieve.
965 *
966 * @return Typeface for the attribute, or {@code null} if not defined.
967 * @throws RuntimeException if the TypedArray has already been recycled.
968 * @throws UnsupportedOperationException if the attribute is defined but is
969 * not a font resource.
970 */
971 @Nullable
972 public Typeface getFont(@StyleableRes int index) {
973 if (mRecycled) {
974 throw new RuntimeException("Cannot make calls to a recycled instance!");
975 }
976
977 final TypedValue value = mValue;
Adam Lesinski7fb38312018-01-23 03:17:26 -0800978 if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
Clara Bayarried00bfd2017-01-20 14:58:21 +0000979 if (value.type == TypedValue.TYPE_ATTRIBUTE) {
980 throw new UnsupportedOperationException(
981 "Failed to resolve attribute at index " + index + ": " + value);
982 }
983 return mResources.getFont(value, value.resourceId);
984 }
985 return null;
986 }
987
988 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800989 * Retrieve the CharSequence[] for the attribute at <var>index</var>.
990 * This gets the resource ID of the selected attribute, and uses
991 * {@link Resources#getTextArray Resources.getTextArray} of the owning
992 * Resources object to retrieve its String[].
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800993 * <p>
994 * This method will throw an exception if the attribute is defined but is
995 * not a text array resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700996 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800997 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -0700998 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800999 * @return CharSequence[] for the attribute, or {@code null} if not
1000 * defined.
1001 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001002 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -07001003 public CharSequence[] getTextArray(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -07001004 if (mRecycled) {
1005 throw new RuntimeException("Cannot make calls to a recycled instance!");
1006 }
1007
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001008 final TypedValue value = mValue;
Adam Lesinski7fb38312018-01-23 03:17:26 -08001009 if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001010 return mResources.getTextArray(value.resourceId);
1011 }
1012 return null;
1013 }
1014
1015 /**
1016 * Retrieve the raw TypedValue for the attribute at <var>index</var>.
Alan Viverettefd274a02014-03-27 15:39:15 -07001017 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001018 * @param index Index of attribute to retrieve.
1019 * @param outValue TypedValue object in which to place the attribute's
1020 * data.
Alan Viverettefd274a02014-03-27 15:39:15 -07001021 *
Adam Lesinski32e75012017-05-09 15:25:37 -07001022 * @return {@code true} if the value was retrieved and not @empty, {@code false} otherwise.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001023 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001024 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -07001025 public boolean getValue(@StyleableRes int index, TypedValue outValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -07001026 if (mRecycled) {
1027 throw new RuntimeException("Cannot make calls to a recycled instance!");
Alan Viverette52b999f2014-03-24 18:00:26 -07001028 }
Alan Viverettefd274a02014-03-27 15:39:15 -07001029
Adam Lesinski7fb38312018-01-23 03:17:26 -08001030 return getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, outValue);
Alan Viverette52b999f2014-03-24 18:00:26 -07001031 }
1032
1033 /**
1034 * Returns the type of attribute at the specified index.
1035 *
1036 * @param index Index of attribute whose type to retrieve.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001037 *
Alan Viverette52b999f2014-03-24 18:00:26 -07001038 * @return Attribute type.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001039 * @throws RuntimeException if the TypedArray has already been recycled.
Alan Viverette52b999f2014-03-24 18:00:26 -07001040 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -07001041 public int getType(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -07001042 if (mRecycled) {
1043 throw new RuntimeException("Cannot make calls to a recycled instance!");
1044 }
1045
Adam Lesinski7fb38312018-01-23 03:17:26 -08001046 index *= AssetManager.STYLE_NUM_ENTRIES;
1047 return mData[index + AssetManager.STYLE_TYPE];
Alan Viverette52b999f2014-03-24 18:00:26 -07001048 }
1049
1050 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001051 * Determines whether there is an attribute at <var>index</var>.
Alan Viverettef2969402014-10-29 17:09:36 -07001052 * <p>
1053 * <strong>Note:</strong> If the attribute was set to {@code @empty} or
1054 * {@code @undefined}, this method returns {@code false}.
Alan Viverettefd274a02014-03-27 15:39:15 -07001055 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001056 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -07001057 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001058 * @return True if the attribute has a value, false otherwise.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001059 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001060 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -07001061 public boolean hasValue(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -07001062 if (mRecycled) {
1063 throw new RuntimeException("Cannot make calls to a recycled instance!");
1064 }
1065
Adam Lesinski7fb38312018-01-23 03:17:26 -08001066 index *= AssetManager.STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001067 final int[] data = mData;
Adam Lesinski7fb38312018-01-23 03:17:26 -08001068 final int type = data[index+AssetManager.STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001069 return type != TypedValue.TYPE_NULL;
1070 }
Alan Viverettefd274a02014-03-27 15:39:15 -07001071
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001072 /**
Alan Viverettef2969402014-10-29 17:09:36 -07001073 * Determines whether there is an attribute at <var>index</var>, returning
1074 * {@code true} if the attribute was explicitly set to {@code @empty} and
1075 * {@code false} only if the attribute was undefined.
1076 *
1077 * @param index Index of attribute to retrieve.
1078 *
1079 * @return True if the attribute has a value or is empty, false otherwise.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001080 * @throws RuntimeException if the TypedArray has already been recycled.
Alan Viverettef2969402014-10-29 17:09:36 -07001081 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -07001082 public boolean hasValueOrEmpty(@StyleableRes int index) {
Alan Viverettef2969402014-10-29 17:09:36 -07001083 if (mRecycled) {
1084 throw new RuntimeException("Cannot make calls to a recycled instance!");
1085 }
1086
Adam Lesinski7fb38312018-01-23 03:17:26 -08001087 index *= AssetManager.STYLE_NUM_ENTRIES;
Alan Viverettef2969402014-10-29 17:09:36 -07001088 final int[] data = mData;
Adam Lesinski7fb38312018-01-23 03:17:26 -08001089 final int type = data[index+AssetManager.STYLE_TYPE];
Alan Viverettef2969402014-10-29 17:09:36 -07001090 return type != TypedValue.TYPE_NULL
Adam Lesinski7fb38312018-01-23 03:17:26 -08001091 || data[index+AssetManager.STYLE_DATA] == TypedValue.DATA_NULL_EMPTY;
Alan Viverettef2969402014-10-29 17:09:36 -07001092 }
1093
1094 /**
Alan Viverettefd274a02014-03-27 15:39:15 -07001095 * Retrieve the raw TypedValue for the attribute at <var>index</var>
1096 * and return a temporary object holding its data. This object is only
1097 * valid until the next call on to {@link TypedArray}.
1098 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001099 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -07001100 *
1101 * @return Returns a TypedValue object if the attribute is defined,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001102 * containing its data; otherwise returns null. (You will not
1103 * receive a TypedValue whose type is TYPE_NULL.)
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001104 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001105 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -07001106 public TypedValue peekValue(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -07001107 if (mRecycled) {
1108 throw new RuntimeException("Cannot make calls to a recycled instance!");
1109 }
1110
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001111 final TypedValue value = mValue;
Adam Lesinski7fb38312018-01-23 03:17:26 -08001112 if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001113 return value;
1114 }
1115 return null;
1116 }
1117
1118 /**
1119 * Returns a message about the parser state suitable for printing error messages.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001120 *
1121 * @return Human-readable description of current parser state.
1122 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001123 */
1124 public String getPositionDescription() {
Alan Viverettefd274a02014-03-27 15:39:15 -07001125 if (mRecycled) {
1126 throw new RuntimeException("Cannot make calls to a recycled instance!");
1127 }
1128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001129 return mXml != null ? mXml.getPositionDescription() : "<internal>";
1130 }
1131
1132 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001133 * Recycles the TypedArray, to be re-used by a later caller. After calling
Alan Viverettefd274a02014-03-27 15:39:15 -07001134 * this function you must not ever touch the typed array again.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001135 *
1136 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001137 */
1138 public void recycle() {
Alan Viverettefd274a02014-03-27 15:39:15 -07001139 if (mRecycled) {
1140 throw new RuntimeException(toString() + " recycled twice!");
1141 }
1142
1143 mRecycled = true;
Alan Viverette8eea3ea2014-02-03 18:40:20 -08001144
Alan Viverette52b999f2014-03-24 18:00:26 -07001145 // These may have been set by the client.
Alan Viverette8eea3ea2014-02-03 18:40:20 -08001146 mXml = null;
Alan Viverette8eea3ea2014-02-03 18:40:20 -08001147 mTheme = null;
Adam Lesinskie60064a2016-07-13 12:09:24 -07001148 mAssets = null;
Alan Viverette52b999f2014-03-24 18:00:26 -07001149
Alan Viverette8b5b25b2014-09-13 19:30:11 -07001150 mResources.mTypedArrayPool.release(this);
Alan Viverette52b999f2014-03-24 18:00:26 -07001151 }
1152
1153 /**
1154 * Extracts theme attributes from a typed array for later resolution using
Alan Viverette9cd14fc2014-06-20 14:45:11 -07001155 * {@link android.content.res.Resources.Theme#resolveAttributes(int[], int[])}.
1156 * Removes the entries from the typed array so that subsequent calls to typed
1157 * getters will return the default value without crashing.
Alan Viverette52b999f2014-03-24 18:00:26 -07001158 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001159 * @return an array of length {@link #getIndexCount()} populated with theme
1160 * attributes, or null if there are no theme attributes in the typed
1161 * array
1162 * @throws RuntimeException if the TypedArray has already been recycled.
Alan Viverette52b999f2014-03-24 18:00:26 -07001163 * @hide
1164 */
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001165 @Nullable
Alan Viverette52b999f2014-03-24 18:00:26 -07001166 public int[] extractThemeAttrs() {
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001167 return extractThemeAttrs(null);
1168 }
1169
1170 /**
1171 * @hide
1172 */
1173 @Nullable
1174 public int[] extractThemeAttrs(@Nullable int[] scrap) {
Alan Viverettefd274a02014-03-27 15:39:15 -07001175 if (mRecycled) {
1176 throw new RuntimeException("Cannot make calls to a recycled instance!");
1177 }
1178
Alan Viverette52b999f2014-03-24 18:00:26 -07001179 int[] attrs = null;
1180
Alan Viverette0cfb8772014-05-14 17:40:53 -07001181 final int[] data = mData;
Alan Viverette1cd46122014-03-25 17:58:50 -07001182 final int N = length();
Alan Viverette52b999f2014-03-24 18:00:26 -07001183 for (int i = 0; i < N; i++) {
Adam Lesinski7fb38312018-01-23 03:17:26 -08001184 final int index = i * AssetManager.STYLE_NUM_ENTRIES;
1185 if (data[index + AssetManager.STYLE_TYPE] != TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001186 // Not an attribute, ignore.
Alan Viverette0cfb8772014-05-14 17:40:53 -07001187 continue;
Alan Viverette52b999f2014-03-24 18:00:26 -07001188 }
Alan Viverette0cfb8772014-05-14 17:40:53 -07001189
1190 // Null the entry so that we can safely call getZzz().
Adam Lesinski7fb38312018-01-23 03:17:26 -08001191 data[index + AssetManager.STYLE_TYPE] = TypedValue.TYPE_NULL;
Alan Viverette0cfb8772014-05-14 17:40:53 -07001192
Adam Lesinski7fb38312018-01-23 03:17:26 -08001193 final int attr = data[index + AssetManager.STYLE_DATA];
Alan Viverette0cfb8772014-05-14 17:40:53 -07001194 if (attr == 0) {
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001195 // Useless data, ignore.
Alan Viverette0cfb8772014-05-14 17:40:53 -07001196 continue;
1197 }
1198
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001199 // Ensure we have a usable attribute array.
Alan Viverette0cfb8772014-05-14 17:40:53 -07001200 if (attrs == null) {
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001201 if (scrap != null && scrap.length == N) {
1202 attrs = scrap;
1203 Arrays.fill(attrs, 0);
1204 } else {
1205 attrs = new int[N];
1206 }
Alan Viverette0cfb8772014-05-14 17:40:53 -07001207 }
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001208
Alan Viverette0cfb8772014-05-14 17:40:53 -07001209 attrs[i] = attr;
Alan Viverette52b999f2014-03-24 18:00:26 -07001210 }
1211
1212 return attrs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001213 }
1214
Alan Viverette8e5e11b2014-07-07 14:06:15 -07001215 /**
1216 * Return a mask of the configuration parameters for which the values in
1217 * this typed array may change.
1218 *
1219 * @return Returns a mask of the changing configuration parameters, as
1220 * defined by {@link android.content.pm.ActivityInfo}.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001221 * @throws RuntimeException if the TypedArray has already been recycled.
Alan Viverette8e5e11b2014-07-07 14:06:15 -07001222 * @see android.content.pm.ActivityInfo
1223 */
Alan Viveretteac85f902016-03-11 15:15:51 -05001224 public @Config int getChangingConfigurations() {
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001225 if (mRecycled) {
1226 throw new RuntimeException("Cannot make calls to a recycled instance!");
1227 }
1228
Alan Viveretteac85f902016-03-11 15:15:51 -05001229 @Config int changingConfig = 0;
Alan Viverette8e5e11b2014-07-07 14:06:15 -07001230
1231 final int[] data = mData;
1232 final int N = length();
1233 for (int i = 0; i < N; i++) {
Adam Lesinski7fb38312018-01-23 03:17:26 -08001234 final int index = i * AssetManager.STYLE_NUM_ENTRIES;
1235 final int type = data[index + AssetManager.STYLE_TYPE];
Alan Viverette8e5e11b2014-07-07 14:06:15 -07001236 if (type == TypedValue.TYPE_NULL) {
1237 continue;
1238 }
Alan Viveretteac85f902016-03-11 15:15:51 -05001239 changingConfig |= ActivityInfo.activityInfoConfigNativeToJava(
Adam Lesinski7fb38312018-01-23 03:17:26 -08001240 data[index + AssetManager.STYLE_CHANGING_CONFIGURATIONS]);
Alan Viverette8e5e11b2014-07-07 14:06:15 -07001241 }
1242 return changingConfig;
1243 }
1244
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001245 private boolean getValueAt(int index, TypedValue outValue) {
1246 final int[] data = mData;
Adam Lesinski7fb38312018-01-23 03:17:26 -08001247 final int type = data[index+AssetManager.STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001248 if (type == TypedValue.TYPE_NULL) {
1249 return false;
1250 }
1251 outValue.type = type;
Adam Lesinski7fb38312018-01-23 03:17:26 -08001252 outValue.data = data[index+AssetManager.STYLE_DATA];
1253 outValue.assetCookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
1254 outValue.resourceId = data[index+AssetManager.STYLE_RESOURCE_ID];
Alan Viveretteac85f902016-03-11 15:15:51 -05001255 outValue.changingConfigurations = ActivityInfo.activityInfoConfigNativeToJava(
Adam Lesinski7fb38312018-01-23 03:17:26 -08001256 data[index + AssetManager.STYLE_CHANGING_CONFIGURATIONS]);
1257 outValue.density = data[index+AssetManager.STYLE_DENSITY];
Gilles Debunne75399682010-08-19 11:26:14 -07001258 outValue.string = (type == TypedValue.TYPE_STRING) ? loadStringValueAt(index) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001259 return true;
1260 }
1261
1262 private CharSequence loadStringValueAt(int index) {
1263 final int[] data = mData;
Adam Lesinski7fb38312018-01-23 03:17:26 -08001264 final int cookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001265 if (cookie < 0) {
1266 if (mXml != null) {
Adam Lesinski7fb38312018-01-23 03:17:26 -08001267 return mXml.getPooledString(
1268 data[index+AssetManager.STYLE_DATA]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001269 }
1270 return null;
1271 }
Adam Lesinski7fb38312018-01-23 03:17:26 -08001272 return mAssets.getPooledStringForCookie(cookie, data[index+AssetManager.STYLE_DATA]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001273 }
1274
John Reckf32adf42016-11-23 10:39:40 -08001275 /** @hide */
1276 protected TypedArray(Resources resources) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001277 mResources = resources;
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001278 mMetrics = mResources.getDisplayMetrics();
1279 mAssets = mResources.getAssets();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001280 }
1281
Alan Viverette562a6a82014-01-31 11:07:29 -08001282 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001283 public String toString() {
1284 return Arrays.toString(mData);
1285 }
Kenny Root15a4d2f2010-03-11 18:20:12 -08001286}