blob: 30d2d5f73206d8dd5bc8fc3e598f11321e355b54 [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 Inwood1c77a112018-08-14 14:06:26 +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.
66 static final int STYLE_NUM_ENTRIES = 6;
67 static final int STYLE_TYPE = 0;
68 static final int STYLE_DATA = 1;
69 static final int STYLE_ASSET_COOKIE = 2;
70 static final int STYLE_RESOURCE_ID = 3;
71 static final int STYLE_CHANGING_CONFIGURATIONS = 4;
72 static final int STYLE_DENSITY = 5;
73
Mathew Inwood1c77a112018-08-14 14:06:26 +010074 @UnsupportedAppUsage
Alan Viverette8b5b25b2014-09-13 19:30:11 -070075 private final Resources mResources;
Mathew Inwood1c77a112018-08-14 14:06:26 +010076 @UnsupportedAppUsage
Adam Lesinskiec05bc02017-04-18 14:42:22 -070077 private DisplayMetrics mMetrics;
Mathew Inwood1c77a112018-08-14 14:06:26 +010078 @UnsupportedAppUsage
Adam Lesinskie60064a2016-07-13 12:09:24 -070079 private AssetManager mAssets;
Alan Viverette8b5b25b2014-09-13 19:30:11 -070080
Mathew Inwood1c77a112018-08-14 14:06:26 +010081 @UnsupportedAppUsage
Alan Viverettefd274a02014-03-27 15:39:15 -070082 private boolean mRecycled;
83
Mathew Inwood1c77a112018-08-14 14:06:26 +010084 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085 /*package*/ XmlBlock.Parser mXml;
Mathew Inwood1c77a112018-08-14 14:06:26 +010086 @UnsupportedAppUsage
Alan Viverette52b999f2014-03-24 18:00:26 -070087 /*package*/ Resources.Theme mTheme;
Mathew Inwood1c77a112018-08-14 14:06:26 +010088 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089 /*package*/ int[] mData;
John Reckf32adf42016-11-23 10:39:40 -080090 /*package*/ long mDataAddress;
Mathew Inwood1c77a112018-08-14 14:06:26 +010091 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 /*package*/ int[] mIndices;
John Reckf32adf42016-11-23 10:39:40 -080093 /*package*/ long mIndicesAddress;
Mathew Inwood1c77a112018-08-14 14:06:26 +010094 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095 /*package*/ int mLength;
Mathew Inwood1c77a112018-08-14 14:06:26 +010096 @UnsupportedAppUsage
Xavier Ducrohet7f9f99ea2011-08-11 10:16:17 -070097 /*package*/ TypedValue mValue = new TypedValue();
Alan Viverette8eea3ea2014-02-03 18:40:20 -080098
John Reckf32adf42016-11-23 10:39:40 -080099 private void resize(int len) {
100 mLength = len;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800101 final int dataLen = len * STYLE_NUM_ENTRIES;
John Reckf32adf42016-11-23 10:39:40 -0800102 final int indicesLen = len + 1;
103 final VMRuntime runtime = VMRuntime.getRuntime();
John Reckabd917d2017-01-04 19:04:25 -0800104 if (mDataAddress == 0 || mData.length < dataLen) {
John Reckf32adf42016-11-23 10:39:40 -0800105 mData = (int[]) runtime.newNonMovableArray(int.class, dataLen);
106 mDataAddress = runtime.addressOf(mData);
107 mIndices = (int[]) runtime.newNonMovableArray(int.class, indicesLen);
108 mIndicesAddress = runtime.addressOf(mIndices);
109 }
110 }
111
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800113 * Returns the number of values in this array.
114 *
115 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 */
117 public int length() {
Alan Viverettefd274a02014-03-27 15:39:15 -0700118 if (mRecycled) {
119 throw new RuntimeException("Cannot make calls to a recycled instance!");
120 }
121
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122 return mLength;
123 }
Alan Viverettefd274a02014-03-27 15:39:15 -0700124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125 /**
Adam Lesinski32e75012017-05-09 15:25:37 -0700126 * Returns the number of indices in the array that actually have data. Attributes with a value
127 * of @empty are included, as this is an explicit indicator.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800128 *
129 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130 */
131 public int getIndexCount() {
Alan Viverettefd274a02014-03-27 15:39:15 -0700132 if (mRecycled) {
133 throw new RuntimeException("Cannot make calls to a recycled instance!");
134 }
135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136 return mIndices[0];
137 }
Alan Viverettefd274a02014-03-27 15:39:15 -0700138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139 /**
Adam Lesinski32e75012017-05-09 15:25:37 -0700140 * Returns an index in the array that has data. Attributes with a value of @empty are included,
141 * as this is an explicit indicator.
Alan Viverettefd274a02014-03-27 15:39:15 -0700142 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143 * @param at The index you would like to returned, ranging from 0 to
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800144 * {@link #getIndexCount()}.
Alan Viverettefd274a02014-03-27 15:39:15 -0700145 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146 * @return The index at the given offset, which can be used with
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800147 * {@link #getValue} and related APIs.
148 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 */
150 public int getIndex(int at) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700151 if (mRecycled) {
152 throw new RuntimeException("Cannot make calls to a recycled instance!");
153 }
154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 return mIndices[1+at];
156 }
Alan Viverettefd274a02014-03-27 15:39:15 -0700157
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800159 * Returns the Resources object this array was loaded from.
160 *
161 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 */
163 public Resources getResources() {
Alan Viverettefd274a02014-03-27 15:39:15 -0700164 if (mRecycled) {
165 throw new RuntimeException("Cannot make calls to a recycled instance!");
166 }
167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 return mResources;
169 }
Alan Viverettefd274a02014-03-27 15:39:15 -0700170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800172 * Retrieves the styled string value for the attribute at <var>index</var>.
173 * <p>
174 * If the attribute is not a string, this method will attempt to coerce
175 * it to a string.
Alan Viverettefd274a02014-03-27 15:39:15 -0700176 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800177 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -0700178 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800179 * @return CharSequence holding string data. May be styled. Returns
180 * {@code null} if the attribute is not defined or could not be
181 * coerced to a string.
182 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700184 public CharSequence getText(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700185 if (mRecycled) {
186 throw new RuntimeException("Cannot make calls to a recycled instance!");
187 }
188
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800189 index *= STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800191 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192 if (type == TypedValue.TYPE_NULL) {
193 return null;
194 } else if (type == TypedValue.TYPE_STRING) {
195 return loadStringValueAt(index);
196 }
197
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800198 final TypedValue v = mValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199 if (getValueAt(index, v)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200 return v.coerceToString();
201 }
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800202
203 // We already checked for TYPE_NULL. This should never happen.
204 throw new RuntimeException("getText of bad type: 0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 }
206
207 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800208 * Retrieves the string value for the attribute at <var>index</var>.
209 * <p>
210 * If the attribute is not a string, this method will attempt to coerce
211 * it to a string.
Alan Viverettefd274a02014-03-27 15:39:15 -0700212 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -0700214 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800215 * @return String holding string data. Any styling information is removed.
216 * Returns {@code null} if the attribute is not defined or could
217 * not be coerced to a string.
218 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219 */
Alan Viverettea6f354b2015-05-18 15:26:57 -0700220 @Nullable
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700221 public String getString(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700222 if (mRecycled) {
223 throw new RuntimeException("Cannot make calls to a recycled instance!");
224 }
225
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800226 index *= STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800228 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229 if (type == TypedValue.TYPE_NULL) {
230 return null;
231 } else if (type == TypedValue.TYPE_STRING) {
232 return loadStringValueAt(index).toString();
233 }
234
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800235 final TypedValue v = mValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236 if (getValueAt(index, v)) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800237 final CharSequence cs = v.coerceToString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800238 return cs != null ? cs.toString() : null;
239 }
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800240
241 // We already checked for TYPE_NULL. This should never happen.
242 throw new RuntimeException("getString 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>, but
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247 * only if that string comes from an immediate value in an XML file. That
248 * is, this does not allow references to string resources, string
249 * attributes, or conversions from other types. As such, this method
250 * will only return strings for TypedArray objects that come from
251 * attributes in an XML file.
Alan Viverettefd274a02014-03-27 15:39:15 -0700252 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -0700254 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800255 * @return String holding string data. Any styling information is removed.
256 * Returns {@code null} if the attribute is not defined or is not
257 * an immediate string value.
258 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700260 public String getNonResourceString(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700261 if (mRecycled) {
262 throw new RuntimeException("Cannot make calls to a recycled instance!");
263 }
264
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800265 index *= STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800267 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 if (type == TypedValue.TYPE_STRING) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800269 final int cookie = data[index + STYLE_ASSET_COOKIE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800270 if (cookie < 0) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800271 return mXml.getPooledString(data[index + STYLE_DATA]).toString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272 }
273 }
274 return null;
275 }
Alan Viverettefd274a02014-03-27 15:39:15 -0700276
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800278 * Retrieves the string value for the attribute at <var>index</var> that is
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800279 * not allowed to change with the given configurations.
Alan Viverettefd274a02014-03-27 15:39:15 -0700280 *
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800281 * @param index Index of attribute to retrieve.
282 * @param allowedChangingConfigs Bit mask of configurations from
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800283 * {@link Configuration}.NATIVE_CONFIG_* that are allowed to change.
Dianne Hackborn1d0b1772013-09-06 14:02:54 -0700284 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800285 * @return String holding string data. Any styling information is removed.
286 * Returns {@code null} if the attribute is not defined.
287 * @throws RuntimeException if the TypedArray has already been recycled.
288 * @hide
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800289 */
Mathew Inwood1c77a112018-08-14 14:06:26 +0100290 @UnsupportedAppUsage
Alan Viveretteac85f902016-03-11 15:15:51 -0500291 public String getNonConfigurationString(@StyleableRes int index,
292 @Config int allowedChangingConfigs) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700293 if (mRecycled) {
294 throw new RuntimeException("Cannot make calls to a recycled instance!");
295 }
296
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800297 index *= STYLE_NUM_ENTRIES;
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800298 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800299 final int type = data[index + STYLE_TYPE];
Alan Viveretteac85f902016-03-11 15:15:51 -0500300 final @Config int changingConfigs = ActivityInfo.activityInfoConfigNativeToJava(
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800301 data[index + STYLE_CHANGING_CONFIGURATIONS]);
Alan Viveretteac85f902016-03-11 15:15:51 -0500302 if ((changingConfigs & ~allowedChangingConfigs) != 0) {
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800303 return null;
304 }
305 if (type == TypedValue.TYPE_NULL) {
306 return null;
307 } else if (type == TypedValue.TYPE_STRING) {
308 return loadStringValueAt(index).toString();
309 }
310
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800311 final TypedValue v = mValue;
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800312 if (getValueAt(index, v)) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800313 final CharSequence cs = v.coerceToString();
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800314 return cs != null ? cs.toString() : null;
315 }
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800316
317 // We already checked for TYPE_NULL. This should never happen.
318 throw new RuntimeException("getNonConfigurationString of bad type: 0x"
319 + Integer.toHexString(type));
Dianne Hackborncf244ad2010-03-09 15:00:30 -0800320 }
321
322 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323 * Retrieve the boolean value for the attribute at <var>index</var>.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800324 * <p>
325 * If the attribute is an integer value, this method will return whether
326 * it is equal to zero. If the attribute is not a boolean or integer value,
327 * this method will attempt to coerce it to an integer using
328 * {@link Integer#decode(String)} and return whether it is equal to zero.
Alan Viverettefd274a02014-03-27 15:39:15 -0700329 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 * @param index Index of attribute to retrieve.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800331 * @param defValue Value to return if the attribute is not defined or
332 * cannot be coerced to an integer.
Alan Viverettefd274a02014-03-27 15:39:15 -0700333 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800334 * @return Boolean value of the attribute, or defValue if the attribute was
335 * not defined or could not be coerced to an integer.
336 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700338 public boolean getBoolean(@StyleableRes int index, boolean defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700339 if (mRecycled) {
340 throw new RuntimeException("Cannot make calls to a recycled instance!");
341 }
342
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800343 index *= STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800345 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346 if (type == TypedValue.TYPE_NULL) {
347 return defValue;
348 } else if (type >= TypedValue.TYPE_FIRST_INT
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800349 && type <= TypedValue.TYPE_LAST_INT) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800350 return data[index + STYLE_DATA] != 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800351 }
352
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800353 final TypedValue v = mValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800354 if (getValueAt(index, v)) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800355 StrictMode.noteResourceMismatch(v);
356 return XmlUtils.convertValueToBoolean(v.coerceToString(), defValue);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800357 }
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800358
359 // We already checked for TYPE_NULL. This should never happen.
360 throw new RuntimeException("getBoolean of bad type: 0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800361 }
362
363 /**
364 * Retrieve the integer value for the attribute at <var>index</var>.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800365 * <p>
366 * If the attribute is not an integer, this method will attempt to coerce
367 * it to an integer using {@link Integer#decode(String)}.
Alan Viverettefd274a02014-03-27 15:39:15 -0700368 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800369 * @param index Index of attribute to retrieve.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800370 * @param defValue Value to return if the attribute is not defined or
371 * cannot be coerced to an integer.
Alan Viverettefd274a02014-03-27 15:39:15 -0700372 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800373 * @return Integer value of the attribute, or defValue if the attribute was
374 * not defined or could not be coerced to an integer.
375 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700377 public int getInt(@StyleableRes int index, int defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700378 if (mRecycled) {
379 throw new RuntimeException("Cannot make calls to a recycled instance!");
380 }
381
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800382 index *= STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800383 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800384 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800385 if (type == TypedValue.TYPE_NULL) {
386 return defValue;
387 } else if (type >= TypedValue.TYPE_FIRST_INT
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800388 && type <= TypedValue.TYPE_LAST_INT) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800389 return data[index + STYLE_DATA];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390 }
391
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800392 final TypedValue v = mValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 if (getValueAt(index, v)) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800394 StrictMode.noteResourceMismatch(v);
395 return XmlUtils.convertValueToInt(v.coerceToString(), defValue);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396 }
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800397
398 // We already checked for TYPE_NULL. This should never happen.
399 throw new RuntimeException("getInt of bad type: 0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 }
401
402 /**
403 * Retrieve the float value for the attribute at <var>index</var>.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800404 * <p>
405 * If the attribute is not a float or an integer, this method will attempt
406 * to coerce it to a float using {@link Float#parseFloat(String)}.
Alan Viverettefd274a02014-03-27 15:39:15 -0700407 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -0700409 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800410 * @return Attribute float value, or defValue if the attribute was
411 * not defined or could not be coerced to a float.
412 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800413 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700414 public float getFloat(@StyleableRes int index, float defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700415 if (mRecycled) {
416 throw new RuntimeException("Cannot make calls to a recycled instance!");
417 }
418
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800419 index *= STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800421 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422 if (type == TypedValue.TYPE_NULL) {
423 return defValue;
424 } else if (type == TypedValue.TYPE_FLOAT) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800425 return Float.intBitsToFloat(data[index + STYLE_DATA]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800426 } else if (type >= TypedValue.TYPE_FIRST_INT
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800427 && type <= TypedValue.TYPE_LAST_INT) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800428 return data[index + STYLE_DATA];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800429 }
430
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800431 final TypedValue v = mValue;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800432 if (getValueAt(index, v)) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800433 final CharSequence str = v.coerceToString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800434 if (str != null) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800435 StrictMode.noteResourceMismatch(v);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800436 return Float.parseFloat(str.toString());
437 }
438 }
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800439
440 // We already checked for TYPE_NULL. This should never happen.
441 throw new RuntimeException("getFloat of bad type: 0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442 }
Alan Viverettefd274a02014-03-27 15:39:15 -0700443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800444 /**
445 * Retrieve the color value for the attribute at <var>index</var>. If
446 * the attribute references a color resource holding a complex
447 * {@link android.content.res.ColorStateList}, then the default color from
448 * the set is returned.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800449 * <p>
450 * This method will throw an exception if the attribute is defined but is
451 * not an integer color or color state list.
Alan Viverettefd274a02014-03-27 15:39:15 -0700452 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800453 * @param index Index of attribute to retrieve.
454 * @param defValue Value to return if the attribute is not defined or
455 * not a resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700456 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800457 * @return Attribute color value, or defValue if not defined.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800458 * @throws RuntimeException if the TypedArray has already been recycled.
459 * @throws UnsupportedOperationException if the attribute is defined but is
460 * not an integer color or color state list.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800461 */
Tor Norbye80756e32015-03-02 09:39:27 -0800462 @ColorInt
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700463 public int getColor(@StyleableRes int index, @ColorInt int defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700464 if (mRecycled) {
465 throw new RuntimeException("Cannot make calls to a recycled instance!");
466 }
467
Alan Viverette5b90e822016-02-24 09:06:47 -0500468 final int attrIndex = index;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800469 index *= STYLE_NUM_ENTRIES;
Alan Viverette5b90e822016-02-24 09:06:47 -0500470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800472 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 if (type == TypedValue.TYPE_NULL) {
474 return defValue;
475 } else if (type >= TypedValue.TYPE_FIRST_INT
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800476 && type <= TypedValue.TYPE_LAST_INT) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800477 return data[index + STYLE_DATA];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800478 } else if (type == TypedValue.TYPE_STRING) {
479 final TypedValue value = mValue;
480 if (getValueAt(index, value)) {
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800481 final ColorStateList csl = mResources.loadColorStateList(
482 value, value.resourceId, mTheme);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800483 return csl.getDefaultColor();
484 }
485 return defValue;
Alan Viverette216d3e62014-07-29 10:35:42 -0700486 } else if (type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette93795052015-03-09 15:32:50 -0700487 final TypedValue value = mValue;
Alan Viverette5b90e822016-02-24 09:06:47 -0500488 getValueAt(index, value);
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800489 throw new UnsupportedOperationException(
Alan Viverette5b90e822016-02-24 09:06:47 -0500490 "Failed to resolve attribute at index " + attrIndex + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800491 }
492
Alan Viverette5b90e822016-02-24 09:06:47 -0500493 throw new UnsupportedOperationException("Can't convert value at index " + attrIndex
494 + " to color: type=0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 }
496
497 /**
Teng-Hui Zhudbee9bb2015-12-15 11:01:27 -0800498 * Retrieve the ComplexColor for the attribute at <var>index</var>.
499 * The value may be either a {@link android.content.res.ColorStateList} which can wrap a simple
500 * color value or a {@link android.content.res.GradientColor}
501 * <p>
502 * This method will return {@code null} if the attribute is not defined or
503 * is not an integer color, color state list or GradientColor.
504 *
505 * @param index Index of attribute to retrieve.
506 *
507 * @return ComplexColor for the attribute, or {@code null} if not defined.
508 * @throws RuntimeException if the attribute if the TypedArray has already
509 * been recycled.
510 * @throws UnsupportedOperationException if the attribute is defined but is
511 * not an integer color, color state list or GradientColor.
Teng-Hui Zhue03c4692016-03-17 10:38:43 -0700512 * @hide
Teng-Hui Zhudbee9bb2015-12-15 11:01:27 -0800513 */
514 @Nullable
515 public ComplexColor getComplexColor(@StyleableRes int index) {
516 if (mRecycled) {
517 throw new RuntimeException("Cannot make calls to a recycled instance!");
518 }
519
520 final TypedValue value = mValue;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800521 if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
Teng-Hui Zhudbee9bb2015-12-15 11:01:27 -0800522 if (value.type == TypedValue.TYPE_ATTRIBUTE) {
523 throw new UnsupportedOperationException(
524 "Failed to resolve attribute at index " + index + ": " + value);
525 }
526 return mResources.loadComplexColor(value, value.resourceId, mTheme);
527 }
528 return null;
529 }
530
531 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800532 * Retrieve the ColorStateList for the attribute at <var>index</var>.
533 * The value may be either a single solid color or a reference to
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800534 * a color or complex {@link android.content.res.ColorStateList}
535 * description.
536 * <p>
537 * This method will return {@code null} if the attribute is not defined or
538 * is not an integer color or color state list.
Alan Viverettefd274a02014-03-27 15:39:15 -0700539 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800540 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -0700541 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800542 * @return ColorStateList for the attribute, or {@code null} if not
543 * defined.
544 * @throws RuntimeException if the attribute if the TypedArray has already
545 * been recycled.
546 * @throws UnsupportedOperationException if the attribute is defined but is
547 * not an integer color or color state list.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800548 */
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800549 @Nullable
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700550 public ColorStateList getColorStateList(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700551 if (mRecycled) {
552 throw new RuntimeException("Cannot make calls to a recycled instance!");
553 }
554
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800555 final TypedValue value = mValue;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800556 if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
Alan Viverette216d3e62014-07-29 10:35:42 -0700557 if (value.type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800558 throw new UnsupportedOperationException(
Alan Viverette93795052015-03-09 15:32:50 -0700559 "Failed to resolve attribute at index " + index + ": " + value);
Alan Viverette216d3e62014-07-29 10:35:42 -0700560 }
Alan Viverette45c4bbb2015-01-05 14:59:19 -0800561 return mResources.loadColorStateList(value, value.resourceId, mTheme);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800562 }
563 return null;
564 }
565
566 /**
567 * Retrieve the integer value for the attribute at <var>index</var>.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800568 * <p>
569 * Unlike {@link #getInt(int, int)}, this method will throw an exception if
570 * the attribute is defined but is not an integer.
Alan Viverettefd274a02014-03-27 15:39:15 -0700571 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800572 * @param index Index of attribute to retrieve.
573 * @param defValue Value to return if the attribute is not defined or
574 * not a resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700575 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800576 * @return Attribute integer value, or defValue if not defined.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800577 * @throws RuntimeException if the TypedArray has already been recycled.
578 * @throws UnsupportedOperationException if the attribute is defined but is
579 * not an integer.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800580 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700581 public int getInteger(@StyleableRes int index, int defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700582 if (mRecycled) {
583 throw new RuntimeException("Cannot make calls to a recycled instance!");
584 }
585
Alan Viverette5b90e822016-02-24 09:06:47 -0500586 final int attrIndex = index;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800587 index *= STYLE_NUM_ENTRIES;
Alan Viverette5b90e822016-02-24 09:06:47 -0500588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800589 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800590 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800591 if (type == TypedValue.TYPE_NULL) {
592 return defValue;
593 } else if (type >= TypedValue.TYPE_FIRST_INT
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800594 && type <= TypedValue.TYPE_LAST_INT) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800595 return data[index + STYLE_DATA];
Alan Viverette216d3e62014-07-29 10:35:42 -0700596 } else if (type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette93795052015-03-09 15:32:50 -0700597 final TypedValue value = mValue;
Alan Viverette5b90e822016-02-24 09:06:47 -0500598 getValueAt(index, value);
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800599 throw new UnsupportedOperationException(
Alan Viverette5b90e822016-02-24 09:06:47 -0500600 "Failed to resolve attribute at index " + attrIndex + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800601 }
602
Alan Viverette5b90e822016-02-24 09:06:47 -0500603 throw new UnsupportedOperationException("Can't convert value at index " + attrIndex
604 + " to integer: type=0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800605 }
606
607 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800608 * Retrieve a dimensional unit attribute at <var>index</var>. Unit
Alan Viverettefd274a02014-03-27 15:39:15 -0700609 * conversions are based on the current {@link DisplayMetrics}
610 * associated with the resources this {@link TypedArray} object
611 * came from.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800612 * <p>
613 * This method will throw an exception if the attribute is defined but is
614 * not a dimension.
Alan Viverettefd274a02014-03-27 15:39:15 -0700615 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800616 * @param index Index of attribute to retrieve.
617 * @param defValue Value to return if the attribute is not defined or
618 * not a resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700619 *
620 * @return Attribute dimension value multiplied by the appropriate
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800621 * metric, or defValue if not defined.
622 * @throws RuntimeException if the TypedArray has already been recycled.
623 * @throws UnsupportedOperationException if the attribute is defined but is
624 * not an integer.
Alan Viverettefd274a02014-03-27 15:39:15 -0700625 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800626 * @see #getDimensionPixelOffset
627 * @see #getDimensionPixelSize
628 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700629 public float getDimension(@StyleableRes int index, float defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700630 if (mRecycled) {
631 throw new RuntimeException("Cannot make calls to a recycled instance!");
632 }
633
Alan Viverette5b90e822016-02-24 09:06:47 -0500634 final int attrIndex = index;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800635 index *= STYLE_NUM_ENTRIES;
Alan Viverette5b90e822016-02-24 09:06:47 -0500636
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800637 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800638 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800639 if (type == TypedValue.TYPE_NULL) {
640 return defValue;
641 } else if (type == TypedValue.TYPE_DIMENSION) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800642 return TypedValue.complexToDimension(data[index + STYLE_DATA], mMetrics);
Alan Viverette216d3e62014-07-29 10:35:42 -0700643 } else if (type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette93795052015-03-09 15:32:50 -0700644 final TypedValue value = mValue;
Alan Viverette5b90e822016-02-24 09:06:47 -0500645 getValueAt(index, value);
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800646 throw new UnsupportedOperationException(
Alan Viverette5b90e822016-02-24 09:06:47 -0500647 "Failed to resolve attribute at index " + attrIndex + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800648 }
649
Alan Viverette5b90e822016-02-24 09:06:47 -0500650 throw new UnsupportedOperationException("Can't convert value at index " + attrIndex
651 + " to dimension: type=0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800652 }
653
654 /**
655 * Retrieve a dimensional unit attribute at <var>index</var> for use
656 * as an offset in raw pixels. This is the same as
657 * {@link #getDimension}, except the returned value is converted to
658 * integer pixels for you. An offset conversion involves simply
659 * truncating the base value to an integer.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800660 * <p>
661 * This method will throw an exception if the attribute is defined but is
662 * not a dimension.
Alan Viverettefd274a02014-03-27 15:39:15 -0700663 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800664 * @param index Index of attribute to retrieve.
665 * @param defValue Value to return if the attribute is not defined or
666 * not a resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700667 *
668 * @return Attribute dimension value multiplied by the appropriate
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800669 * metric and truncated to integer pixels, or defValue if not defined.
670 * @throws RuntimeException if the TypedArray has already been recycled.
671 * @throws UnsupportedOperationException if the attribute is defined but is
672 * not an integer.
Alan Viverettefd274a02014-03-27 15:39:15 -0700673 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800674 * @see #getDimension
675 * @see #getDimensionPixelSize
676 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700677 public int getDimensionPixelOffset(@StyleableRes int index, int defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700678 if (mRecycled) {
679 throw new RuntimeException("Cannot make calls to a recycled instance!");
680 }
681
Alan Viverette5b90e822016-02-24 09:06:47 -0500682 final int attrIndex = index;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800683 index *= STYLE_NUM_ENTRIES;
Alan Viverette5b90e822016-02-24 09:06:47 -0500684
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800685 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800686 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800687 if (type == TypedValue.TYPE_NULL) {
688 return defValue;
689 } else if (type == TypedValue.TYPE_DIMENSION) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800690 return TypedValue.complexToDimensionPixelOffset(data[index + STYLE_DATA], mMetrics);
Alan Viverette216d3e62014-07-29 10:35:42 -0700691 } else if (type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette93795052015-03-09 15:32:50 -0700692 final TypedValue value = mValue;
Alan Viverette5b90e822016-02-24 09:06:47 -0500693 getValueAt(index, value);
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800694 throw new UnsupportedOperationException(
Alan Viverette5b90e822016-02-24 09:06:47 -0500695 "Failed to resolve attribute at index " + attrIndex + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800696 }
697
Alan Viverette5b90e822016-02-24 09:06:47 -0500698 throw new UnsupportedOperationException("Can't convert value at index " + attrIndex
699 + " to dimension: type=0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800700 }
701
702 /**
703 * Retrieve a dimensional unit attribute at <var>index</var> for use
704 * as a size in raw pixels. This is the same as
705 * {@link #getDimension}, except the returned value is converted to
706 * integer pixels for use as a size. A size conversion involves
707 * rounding the base value, and ensuring that a non-zero base value
708 * is at least one pixel in size.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800709 * <p>
710 * This method will throw an exception if the attribute is defined but is
711 * not a dimension.
Alan Viverettefd274a02014-03-27 15:39:15 -0700712 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800713 * @param index Index of attribute to retrieve.
714 * @param defValue Value to return if the attribute is not defined or
715 * not a resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700716 *
717 * @return Attribute dimension value multiplied by the appropriate
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800718 * metric and truncated to integer pixels, or defValue if not defined.
719 * @throws RuntimeException if the TypedArray has already been recycled.
720 * @throws UnsupportedOperationException if the attribute is defined but is
721 * not a dimension.
Alan Viverettefd274a02014-03-27 15:39:15 -0700722 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723 * @see #getDimension
724 * @see #getDimensionPixelOffset
725 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700726 public int getDimensionPixelSize(@StyleableRes int index, int defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700727 if (mRecycled) {
728 throw new RuntimeException("Cannot make calls to a recycled instance!");
729 }
730
Alan Viverette5b90e822016-02-24 09:06:47 -0500731 final int attrIndex = index;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800732 index *= STYLE_NUM_ENTRIES;
Alan Viverette5b90e822016-02-24 09:06:47 -0500733
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800734 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800735 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800736 if (type == TypedValue.TYPE_NULL) {
737 return defValue;
738 } else if (type == TypedValue.TYPE_DIMENSION) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800739 return TypedValue.complexToDimensionPixelSize(data[index + STYLE_DATA], mMetrics);
Alan Viverette216d3e62014-07-29 10:35:42 -0700740 } else if (type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette93795052015-03-09 15:32:50 -0700741 final TypedValue value = mValue;
Alan Viverette5b90e822016-02-24 09:06:47 -0500742 getValueAt(index, value);
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800743 throw new UnsupportedOperationException(
Alan Viverette5b90e822016-02-24 09:06:47 -0500744 "Failed to resolve attribute at index " + attrIndex + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800745 }
746
Alan Viverette5b90e822016-02-24 09:06:47 -0500747 throw new UnsupportedOperationException("Can't convert value at index " + attrIndex
748 + " to dimension: type=0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800749 }
750
751 /**
752 * Special version of {@link #getDimensionPixelSize} for retrieving
753 * {@link android.view.ViewGroup}'s layout_width and layout_height
754 * attributes. This is only here for performance reasons; applications
755 * should use {@link #getDimensionPixelSize}.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800756 * <p>
757 * This method will throw an exception if the attribute is defined but is
758 * not a dimension or integer (enum).
Alan Viverettefd274a02014-03-27 15:39:15 -0700759 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800760 * @param index Index of the attribute to retrieve.
761 * @param name Textual name of attribute for error reporting.
Alan Viverettefd274a02014-03-27 15:39:15 -0700762 *
763 * @return Attribute dimension value multiplied by the appropriate
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800764 * metric and truncated to integer pixels.
765 * @throws RuntimeException if the TypedArray has already been recycled.
766 * @throws UnsupportedOperationException if the attribute is defined but is
767 * not a dimension or integer (enum).
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800768 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700769 public int getLayoutDimension(@StyleableRes int index, String name) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700770 if (mRecycled) {
771 throw new RuntimeException("Cannot make calls to a recycled instance!");
772 }
773
Alan Viverette5b90e822016-02-24 09:06:47 -0500774 final int attrIndex = index;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800775 index *= STYLE_NUM_ENTRIES;
Alan Viverette5b90e822016-02-24 09:06:47 -0500776
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800777 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800778 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800779 if (type >= TypedValue.TYPE_FIRST_INT
780 && type <= TypedValue.TYPE_LAST_INT) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800781 return data[index + STYLE_DATA];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800782 } else if (type == TypedValue.TYPE_DIMENSION) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800783 return TypedValue.complexToDimensionPixelSize(data[index + STYLE_DATA], mMetrics);
Alan Viverette216d3e62014-07-29 10:35:42 -0700784 } else if (type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette93795052015-03-09 15:32:50 -0700785 final TypedValue value = mValue;
Alan Viverette5b90e822016-02-24 09:06:47 -0500786 getValueAt(index, value);
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800787 throw new UnsupportedOperationException(
Alan Viverette5b90e822016-02-24 09:06:47 -0500788 "Failed to resolve attribute at index " + attrIndex + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800789 }
790
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800791 throw new UnsupportedOperationException(getPositionDescription()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800792 + ": You must supply a " + name + " attribute.");
793 }
Alan Viverettefd274a02014-03-27 15:39:15 -0700794
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800795 /**
796 * Special version of {@link #getDimensionPixelSize} for retrieving
797 * {@link android.view.ViewGroup}'s layout_width and layout_height
798 * attributes. This is only here for performance reasons; applications
799 * should use {@link #getDimensionPixelSize}.
Alan Viverettefd274a02014-03-27 15:39:15 -0700800 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801 * @param index Index of the attribute to retrieve.
802 * @param defValue The default value to return if this attribute is not
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800803 * default or contains the wrong type of data.
Alan Viverettefd274a02014-03-27 15:39:15 -0700804 *
805 * @return Attribute dimension value multiplied by the appropriate
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800806 * metric and truncated to integer pixels.
807 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800808 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700809 public int getLayoutDimension(@StyleableRes int index, int defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700810 if (mRecycled) {
811 throw new RuntimeException("Cannot make calls to a recycled instance!");
812 }
813
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800814 index *= STYLE_NUM_ENTRIES;
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);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800822 }
823
824 return defValue;
825 }
826
827 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800828 * Retrieves a fractional unit attribute at <var>index</var>.
Alan Viverettefd274a02014-03-27 15:39:15 -0700829 *
830 * @param index Index of attribute to retrieve.
831 * @param base The base value of this fraction. In other words, a
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800832 * standard fraction is multiplied by this value.
Alan Viverettefd274a02014-03-27 15:39:15 -0700833 * @param pbase The parent base value of this fraction. In other
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800834 * words, a parent fraction (nn%p) is multiplied by this
835 * value.
836 * @param defValue Value to return if the attribute is not defined or
837 * not a resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700838 *
839 * @return Attribute fractional value multiplied by the appropriate
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800840 * base value, or defValue if not defined.
841 * @throws RuntimeException if the TypedArray has already been recycled.
842 * @throws UnsupportedOperationException if the attribute is defined but is
843 * not a fraction.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800844 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700845 public float getFraction(@StyleableRes int index, int base, int pbase, float defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700846 if (mRecycled) {
847 throw new RuntimeException("Cannot make calls to a recycled instance!");
848 }
849
Alan Viverette5b90e822016-02-24 09:06:47 -0500850 final int attrIndex = index;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800851 index *= STYLE_NUM_ENTRIES;
Alan Viverette5b90e822016-02-24 09:06:47 -0500852
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_NULL) {
856 return defValue;
857 } else if (type == TypedValue.TYPE_FRACTION) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800858 return TypedValue.complexToFraction(data[index + STYLE_DATA], base, pbase);
Alan Viverette216d3e62014-07-29 10:35:42 -0700859 } else if (type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette93795052015-03-09 15:32:50 -0700860 final TypedValue value = mValue;
Alan Viverette5b90e822016-02-24 09:06:47 -0500861 getValueAt(index, value);
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800862 throw new UnsupportedOperationException(
Alan Viverette5b90e822016-02-24 09:06:47 -0500863 "Failed to resolve attribute at index " + attrIndex + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864 }
865
Alan Viverette5b90e822016-02-24 09:06:47 -0500866 throw new UnsupportedOperationException("Can't convert value at index " + attrIndex
867 + " to fraction: type=0x" + Integer.toHexString(type));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800868 }
869
870 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800871 * Retrieves the resource identifier for the attribute at
Alan Viverettefd274a02014-03-27 15:39:15 -0700872 * <var>index</var>. Note that attribute resource as resolved when
873 * the overall {@link TypedArray} object is retrieved. As a
874 * result, this function will return the resource identifier of the
875 * final resource value that was found, <em>not</em> necessarily the
876 * original resource that was specified by the attribute.
877 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800878 * @param index Index of attribute to retrieve.
879 * @param defValue Value to return if the attribute is not defined or
880 * not a resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700881 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800882 * @return Attribute resource identifier, or defValue if not defined.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800883 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800884 */
Tor Norbye7b9c9122013-05-30 16:48:33 -0700885 @AnyRes
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700886 public int getResourceId(@StyleableRes int index, int defValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700887 if (mRecycled) {
888 throw new RuntimeException("Cannot make calls to a recycled instance!");
889 }
890
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800891 index *= STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800892 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800893 if (data[index + STYLE_TYPE] != TypedValue.TYPE_NULL) {
894 final int resid = data[index + STYLE_RESOURCE_ID];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800895 if (resid != 0) {
896 return resid;
897 }
898 }
899 return defValue;
900 }
901
902 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800903 * Retrieves the theme attribute resource identifier for the attribute at
Alan Viverette500c5602014-07-29 11:30:35 -0700904 * <var>index</var>.
905 *
906 * @param index Index of attribute to retrieve.
907 * @param defValue Value to return if the attribute is not defined or not a
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800908 * resource.
909 *
Alan Viverette500c5602014-07-29 11:30:35 -0700910 * @return Theme attribute resource identifier, or defValue if not defined.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800911 * @throws RuntimeException if the TypedArray has already been recycled.
Alan Viverette500c5602014-07-29 11:30:35 -0700912 * @hide
913 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700914 public int getThemeAttributeId(@StyleableRes int index, int defValue) {
Alan Viverette500c5602014-07-29 11:30:35 -0700915 if (mRecycled) {
916 throw new RuntimeException("Cannot make calls to a recycled instance!");
917 }
918
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800919 index *= STYLE_NUM_ENTRIES;
Alan Viverette500c5602014-07-29 11:30:35 -0700920 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800921 if (data[index + STYLE_TYPE] == TypedValue.TYPE_ATTRIBUTE) {
922 return data[index + STYLE_DATA];
Alan Viverette500c5602014-07-29 11:30:35 -0700923 }
924 return defValue;
925 }
926
927 /**
Alan Viverettefde4e3b2014-09-22 16:19:51 -0700928 * Retrieve the Drawable for the attribute at <var>index</var>.
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800929 * <p>
930 * This method will throw an exception if the attribute is defined but is
931 * not a color or drawable resource.
Alan Viverettefd274a02014-03-27 15:39:15 -0700932 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -0700934 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800935 * @return Drawable for the attribute, or {@code null} if not defined.
936 * @throws RuntimeException if the TypedArray has already been recycled.
937 * @throws UnsupportedOperationException if the attribute is defined but is
938 * not a color or drawable resource.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800939 */
Alan Viverettefde4e3b2014-09-22 16:19:51 -0700940 @Nullable
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -0700941 public Drawable getDrawable(@StyleableRes int index) {
Adam Lesinski50954d22017-04-14 18:41:52 -0700942 return getDrawableForDensity(index, 0);
943 }
944
945 /**
946 * Version of {@link #getDrawable(int)} that accepts an override density.
947 * @hide
948 */
949 @Nullable
950 public Drawable getDrawableForDensity(@StyleableRes int index, int density) {
Alan Viverettefd274a02014-03-27 15:39:15 -0700951 if (mRecycled) {
952 throw new RuntimeException("Cannot make calls to a recycled instance!");
953 }
954
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800955 final TypedValue value = mValue;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800956 if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
Alan Viverette216d3e62014-07-29 10:35:42 -0700957 if (value.type == TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette6bbb47b2015-01-05 18:12:44 -0800958 throw new UnsupportedOperationException(
Alan Viverette93795052015-03-09 15:32:50 -0700959 "Failed to resolve attribute at index " + index + ": " + value);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800960 }
Adam Lesinski50954d22017-04-14 18:41:52 -0700961
962 if (density > 0) {
963 // If the density is overridden, the value in the TypedArray will not reflect this.
964 // Do a separate lookup of the resourceId with the density override.
965 mResources.getValueForDensity(value.resourceId, density, value, true);
966 }
967 return mResources.loadDrawable(value, value.resourceId, density, mTheme);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800968 }
969 return null;
970 }
971
972 /**
Clara Bayarried00bfd2017-01-20 14:58:21 +0000973 * Retrieve the Typeface for the attribute at <var>index</var>.
974 * <p>
975 * This method will throw an exception if the attribute is defined but is
976 * not a font.
977 *
978 * @param index Index of attribute to retrieve.
979 *
980 * @return Typeface for the attribute, or {@code null} if not defined.
981 * @throws RuntimeException if the TypedArray has already been recycled.
982 * @throws UnsupportedOperationException if the attribute is defined but is
983 * not a font resource.
984 */
985 @Nullable
986 public Typeface getFont(@StyleableRes int index) {
987 if (mRecycled) {
988 throw new RuntimeException("Cannot make calls to a recycled instance!");
989 }
990
991 final TypedValue value = mValue;
Adam Lesinskibebfcc42018-02-12 14:27:46 -0800992 if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
Clara Bayarried00bfd2017-01-20 14:58:21 +0000993 if (value.type == TypedValue.TYPE_ATTRIBUTE) {
994 throw new UnsupportedOperationException(
995 "Failed to resolve attribute at index " + index + ": " + value);
996 }
997 return mResources.getFont(value, value.resourceId);
998 }
999 return null;
1000 }
1001
1002 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001003 * Retrieve the CharSequence[] for the attribute at <var>index</var>.
1004 * This gets the resource ID of the selected attribute, and uses
1005 * {@link Resources#getTextArray Resources.getTextArray} of the owning
1006 * Resources object to retrieve its String[].
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001007 * <p>
1008 * This method will throw an exception if the attribute is defined but is
1009 * not a text array resource.
Alan Viverettefd274a02014-03-27 15:39:15 -07001010 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001011 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -07001012 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001013 * @return CharSequence[] for the attribute, or {@code null} if not
1014 * defined.
1015 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001016 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -07001017 public CharSequence[] getTextArray(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -07001018 if (mRecycled) {
1019 throw new RuntimeException("Cannot make calls to a recycled instance!");
1020 }
1021
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001022 final TypedValue value = mValue;
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001023 if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001024 return mResources.getTextArray(value.resourceId);
1025 }
1026 return null;
1027 }
1028
1029 /**
1030 * Retrieve the raw TypedValue for the attribute at <var>index</var>.
Alan Viverettefd274a02014-03-27 15:39:15 -07001031 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001032 * @param index Index of attribute to retrieve.
1033 * @param outValue TypedValue object in which to place the attribute's
1034 * data.
Alan Viverettefd274a02014-03-27 15:39:15 -07001035 *
Adam Lesinski32e75012017-05-09 15:25:37 -07001036 * @return {@code true} if the value was retrieved and not @empty, {@code false} otherwise.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001037 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001038 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -07001039 public boolean getValue(@StyleableRes int index, TypedValue outValue) {
Alan Viverettefd274a02014-03-27 15:39:15 -07001040 if (mRecycled) {
1041 throw new RuntimeException("Cannot make calls to a recycled instance!");
Alan Viverette52b999f2014-03-24 18:00:26 -07001042 }
Alan Viverettefd274a02014-03-27 15:39:15 -07001043
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001044 return getValueAt(index * STYLE_NUM_ENTRIES, outValue);
Alan Viverette52b999f2014-03-24 18:00:26 -07001045 }
1046
1047 /**
1048 * Returns the type of attribute at the specified index.
1049 *
1050 * @param index Index of attribute whose type to retrieve.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001051 *
Alan Viverette52b999f2014-03-24 18:00:26 -07001052 * @return Attribute type.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001053 * @throws RuntimeException if the TypedArray has already been recycled.
Alan Viverette52b999f2014-03-24 18:00:26 -07001054 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -07001055 public int getType(@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
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001060 index *= STYLE_NUM_ENTRIES;
1061 return mData[index + STYLE_TYPE];
Alan Viverette52b999f2014-03-24 18:00:26 -07001062 }
1063
1064 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001065 * Determines whether there is an attribute at <var>index</var>.
Alan Viverettef2969402014-10-29 17:09:36 -07001066 * <p>
1067 * <strong>Note:</strong> If the attribute was set to {@code @empty} or
1068 * {@code @undefined}, this method returns {@code false}.
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.
Alan Viverettefd274a02014-03-27 15:39:15 -07001071 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001072 * @return True if the attribute has a value, false otherwise.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001073 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001074 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -07001075 public boolean hasValue(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -07001076 if (mRecycled) {
1077 throw new RuntimeException("Cannot make calls to a recycled instance!");
1078 }
1079
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001080 index *= STYLE_NUM_ENTRIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001081 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001082 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001083 return type != TypedValue.TYPE_NULL;
1084 }
Alan Viverettefd274a02014-03-27 15:39:15 -07001085
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001086 /**
Alan Viverettef2969402014-10-29 17:09:36 -07001087 * Determines whether there is an attribute at <var>index</var>, returning
1088 * {@code true} if the attribute was explicitly set to {@code @empty} and
1089 * {@code false} only if the attribute was undefined.
1090 *
1091 * @param index Index of attribute to retrieve.
1092 *
1093 * @return True if the attribute has a value or is empty, false otherwise.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001094 * @throws RuntimeException if the TypedArray has already been recycled.
Alan Viverettef2969402014-10-29 17:09:36 -07001095 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -07001096 public boolean hasValueOrEmpty(@StyleableRes int index) {
Alan Viverettef2969402014-10-29 17:09:36 -07001097 if (mRecycled) {
1098 throw new RuntimeException("Cannot make calls to a recycled instance!");
1099 }
1100
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001101 index *= STYLE_NUM_ENTRIES;
Alan Viverettef2969402014-10-29 17:09:36 -07001102 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001103 final int type = data[index + STYLE_TYPE];
Alan Viverettef2969402014-10-29 17:09:36 -07001104 return type != TypedValue.TYPE_NULL
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001105 || data[index + STYLE_DATA] == TypedValue.DATA_NULL_EMPTY;
Alan Viverettef2969402014-10-29 17:09:36 -07001106 }
1107
1108 /**
Alan Viverettefd274a02014-03-27 15:39:15 -07001109 * Retrieve the raw TypedValue for the attribute at <var>index</var>
1110 * and return a temporary object holding its data. This object is only
1111 * valid until the next call on to {@link TypedArray}.
1112 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001113 * @param index Index of attribute to retrieve.
Alan Viverettefd274a02014-03-27 15:39:15 -07001114 *
1115 * @return Returns a TypedValue object if the attribute is defined,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001116 * containing its data; otherwise returns null. (You will not
1117 * receive a TypedValue whose type is TYPE_NULL.)
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001118 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001119 */
Deepanshu Guptad7bb3f82015-08-05 16:38:21 -07001120 public TypedValue peekValue(@StyleableRes int index) {
Alan Viverettefd274a02014-03-27 15:39:15 -07001121 if (mRecycled) {
1122 throw new RuntimeException("Cannot make calls to a recycled instance!");
1123 }
1124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001125 final TypedValue value = mValue;
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001126 if (getValueAt(index * STYLE_NUM_ENTRIES, value)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001127 return value;
1128 }
1129 return null;
1130 }
1131
1132 /**
1133 * Returns a message about the parser state suitable for printing error messages.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001134 *
1135 * @return Human-readable description of current parser state.
1136 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001137 */
1138 public String getPositionDescription() {
Alan Viverettefd274a02014-03-27 15:39:15 -07001139 if (mRecycled) {
1140 throw new RuntimeException("Cannot make calls to a recycled instance!");
1141 }
1142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001143 return mXml != null ? mXml.getPositionDescription() : "<internal>";
1144 }
1145
1146 /**
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001147 * Recycles the TypedArray, to be re-used by a later caller. After calling
Alan Viverettefd274a02014-03-27 15:39:15 -07001148 * this function you must not ever touch the typed array again.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001149 *
1150 * @throws RuntimeException if the TypedArray has already been recycled.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001151 */
1152 public void recycle() {
Alan Viverettefd274a02014-03-27 15:39:15 -07001153 if (mRecycled) {
1154 throw new RuntimeException(toString() + " recycled twice!");
1155 }
1156
1157 mRecycled = true;
Alan Viverette8eea3ea2014-02-03 18:40:20 -08001158
Alan Viverette52b999f2014-03-24 18:00:26 -07001159 // These may have been set by the client.
Alan Viverette8eea3ea2014-02-03 18:40:20 -08001160 mXml = null;
Alan Viverette8eea3ea2014-02-03 18:40:20 -08001161 mTheme = null;
Adam Lesinskie60064a2016-07-13 12:09:24 -07001162 mAssets = null;
Alan Viverette52b999f2014-03-24 18:00:26 -07001163
Alan Viverette8b5b25b2014-09-13 19:30:11 -07001164 mResources.mTypedArrayPool.release(this);
Alan Viverette52b999f2014-03-24 18:00:26 -07001165 }
1166
1167 /**
1168 * Extracts theme attributes from a typed array for later resolution using
Alan Viverette9cd14fc2014-06-20 14:45:11 -07001169 * {@link android.content.res.Resources.Theme#resolveAttributes(int[], int[])}.
1170 * Removes the entries from the typed array so that subsequent calls to typed
1171 * getters will return the default value without crashing.
Alan Viverette52b999f2014-03-24 18:00:26 -07001172 *
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001173 * @return an array of length {@link #getIndexCount()} populated with theme
1174 * attributes, or null if there are no theme attributes in the typed
1175 * array
1176 * @throws RuntimeException if the TypedArray has already been recycled.
Alan Viverette52b999f2014-03-24 18:00:26 -07001177 * @hide
1178 */
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001179 @Nullable
Mathew Inwood1c77a112018-08-14 14:06:26 +01001180 @UnsupportedAppUsage
Alan Viverette52b999f2014-03-24 18:00:26 -07001181 public int[] extractThemeAttrs() {
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001182 return extractThemeAttrs(null);
1183 }
1184
1185 /**
1186 * @hide
1187 */
1188 @Nullable
Mathew Inwood1c77a112018-08-14 14:06:26 +01001189 @UnsupportedAppUsage
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001190 public int[] extractThemeAttrs(@Nullable int[] scrap) {
Alan Viverettefd274a02014-03-27 15:39:15 -07001191 if (mRecycled) {
1192 throw new RuntimeException("Cannot make calls to a recycled instance!");
1193 }
1194
Alan Viverette52b999f2014-03-24 18:00:26 -07001195 int[] attrs = null;
1196
Alan Viverette0cfb8772014-05-14 17:40:53 -07001197 final int[] data = mData;
Alan Viverette1cd46122014-03-25 17:58:50 -07001198 final int N = length();
Alan Viverette52b999f2014-03-24 18:00:26 -07001199 for (int i = 0; i < N; i++) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001200 final int index = i * STYLE_NUM_ENTRIES;
1201 if (data[index + STYLE_TYPE] != TypedValue.TYPE_ATTRIBUTE) {
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001202 // Not an attribute, ignore.
Alan Viverette0cfb8772014-05-14 17:40:53 -07001203 continue;
Alan Viverette52b999f2014-03-24 18:00:26 -07001204 }
Alan Viverette0cfb8772014-05-14 17:40:53 -07001205
1206 // Null the entry so that we can safely call getZzz().
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001207 data[index + STYLE_TYPE] = TypedValue.TYPE_NULL;
Alan Viverette0cfb8772014-05-14 17:40:53 -07001208
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001209 final int attr = data[index + STYLE_DATA];
Alan Viverette0cfb8772014-05-14 17:40:53 -07001210 if (attr == 0) {
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001211 // Useless data, ignore.
Alan Viverette0cfb8772014-05-14 17:40:53 -07001212 continue;
1213 }
1214
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001215 // Ensure we have a usable attribute array.
Alan Viverette0cfb8772014-05-14 17:40:53 -07001216 if (attrs == null) {
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001217 if (scrap != null && scrap.length == N) {
1218 attrs = scrap;
1219 Arrays.fill(attrs, 0);
1220 } else {
1221 attrs = new int[N];
1222 }
Alan Viverette0cfb8772014-05-14 17:40:53 -07001223 }
Alan Viverette45c4bbb2015-01-05 14:59:19 -08001224
Alan Viverette0cfb8772014-05-14 17:40:53 -07001225 attrs[i] = attr;
Alan Viverette52b999f2014-03-24 18:00:26 -07001226 }
1227
1228 return attrs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001229 }
1230
Alan Viverette8e5e11b2014-07-07 14:06:15 -07001231 /**
1232 * Return a mask of the configuration parameters for which the values in
1233 * this typed array may change.
1234 *
1235 * @return Returns a mask of the changing configuration parameters, as
1236 * defined by {@link android.content.pm.ActivityInfo}.
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001237 * @throws RuntimeException if the TypedArray has already been recycled.
Alan Viverette8e5e11b2014-07-07 14:06:15 -07001238 * @see android.content.pm.ActivityInfo
1239 */
Alan Viveretteac85f902016-03-11 15:15:51 -05001240 public @Config int getChangingConfigurations() {
Alan Viverette6bbb47b2015-01-05 18:12:44 -08001241 if (mRecycled) {
1242 throw new RuntimeException("Cannot make calls to a recycled instance!");
1243 }
1244
Alan Viveretteac85f902016-03-11 15:15:51 -05001245 @Config int changingConfig = 0;
Alan Viverette8e5e11b2014-07-07 14:06:15 -07001246
1247 final int[] data = mData;
1248 final int N = length();
1249 for (int i = 0; i < N; i++) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001250 final int index = i * STYLE_NUM_ENTRIES;
1251 final int type = data[index + STYLE_TYPE];
Alan Viverette8e5e11b2014-07-07 14:06:15 -07001252 if (type == TypedValue.TYPE_NULL) {
1253 continue;
1254 }
Alan Viveretteac85f902016-03-11 15:15:51 -05001255 changingConfig |= ActivityInfo.activityInfoConfigNativeToJava(
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001256 data[index + STYLE_CHANGING_CONFIGURATIONS]);
Alan Viverette8e5e11b2014-07-07 14:06:15 -07001257 }
1258 return changingConfig;
1259 }
1260
Mathew Inwood1c77a112018-08-14 14:06:26 +01001261 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001262 private boolean getValueAt(int index, TypedValue outValue) {
1263 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001264 final int type = data[index + STYLE_TYPE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001265 if (type == TypedValue.TYPE_NULL) {
1266 return false;
1267 }
1268 outValue.type = type;
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001269 outValue.data = data[index + STYLE_DATA];
1270 outValue.assetCookie = data[index + STYLE_ASSET_COOKIE];
1271 outValue.resourceId = data[index + STYLE_RESOURCE_ID];
Alan Viveretteac85f902016-03-11 15:15:51 -05001272 outValue.changingConfigurations = ActivityInfo.activityInfoConfigNativeToJava(
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001273 data[index + STYLE_CHANGING_CONFIGURATIONS]);
1274 outValue.density = data[index + STYLE_DENSITY];
Gilles Debunne75399682010-08-19 11:26:14 -07001275 outValue.string = (type == TypedValue.TYPE_STRING) ? loadStringValueAt(index) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001276 return true;
1277 }
1278
1279 private CharSequence loadStringValueAt(int index) {
1280 final int[] data = mData;
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001281 final int cookie = data[index + STYLE_ASSET_COOKIE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001282 if (cookie < 0) {
1283 if (mXml != null) {
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001284 return mXml.getPooledString(data[index + STYLE_DATA]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001285 }
1286 return null;
1287 }
Adam Lesinskibebfcc42018-02-12 14:27:46 -08001288 return mAssets.getPooledStringForCookie(cookie, data[index + STYLE_DATA]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001289 }
1290
John Reckf32adf42016-11-23 10:39:40 -08001291 /** @hide */
1292 protected TypedArray(Resources resources) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001293 mResources = resources;
Adam Lesinskifb302cc2016-02-29 16:50:38 -08001294 mMetrics = mResources.getDisplayMetrics();
1295 mAssets = mResources.getAssets();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001296 }
1297
Alan Viverette562a6a82014-01-31 11:07:29 -08001298 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001299 public String toString() {
1300 return Arrays.toString(mData);
1301 }
Kenny Root15a4d2f2010-03-11 18:20:12 -08001302}