1ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski/* 2ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Copyright (C) 2008 The Android Open Source Project 3ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 4ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 5ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * you may not use this file except in compliance with the License. 6ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * You may obtain a copy of the License at 7ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 8ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 9ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 10ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Unless required by applicable law or agreed to in writing, software 11ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 12ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * See the License for the specific language governing permissions and 14ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * limitations under the License. 15ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 16ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 17ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskipackage android.content.res; 18ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 1937e93696222aed44026f6423dd05ebc7c3c72b71Deepanshu Guptaimport com.android.ide.common.rendering.api.ArrayResourceValue; 20ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.ide.common.rendering.api.AttrResourceValue; 21ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.ide.common.rendering.api.LayoutLog; 22ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.ide.common.rendering.api.RenderResources; 23ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.ide.common.rendering.api.ResourceValue; 24ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.ide.common.rendering.api.StyleResourceValue; 25ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.internal.util.XmlUtils; 26ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.layoutlib.bridge.Bridge; 27ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.layoutlib.bridge.android.BridgeContext; 28ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.layoutlib.bridge.impl.ResourceHelper; 29ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.resources.ResourceType; 30ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 31442aee6bc1abfb143dcfa1ba60d696e576d066c4Deepanshu Guptaimport android.annotation.Nullable; 32ca617d8a82e46474f597fe9a9b13bf0abc89f0baDeepanshu Guptaimport android.content.res.Resources.Theme; 337c22a707de1ed939ebd91079dff9df6cd5ffd401Diego Perezimport android.graphics.Typeface; 34ef221c3b4f85123ac1ba21b46e36545c91508edaDiego Perezimport android.graphics.Typeface_Accessor; 35ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport android.graphics.drawable.Drawable; 36ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport android.util.DisplayMetrics; 37ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport android.util.TypedValue; 38ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport android.view.LayoutInflater_Delegate; 39ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport android.view.ViewGroup.LayoutParams; 40ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 416f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Guptaimport java.util.ArrayList; 42ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.util.Arrays; 43ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.util.Map; 44ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 451756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Guptaimport static android.util.TypedValue.TYPE_ATTRIBUTE; 461756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Guptaimport static android.util.TypedValue.TYPE_DIMENSION; 471756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Guptaimport static android.util.TypedValue.TYPE_FLOAT; 481756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Guptaimport static android.util.TypedValue.TYPE_INT_BOOLEAN; 491756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Guptaimport static android.util.TypedValue.TYPE_INT_COLOR_ARGB4; 501756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Guptaimport static android.util.TypedValue.TYPE_INT_COLOR_ARGB8; 511756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Guptaimport static android.util.TypedValue.TYPE_INT_COLOR_RGB4; 521756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Guptaimport static android.util.TypedValue.TYPE_INT_COLOR_RGB8; 531756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Guptaimport static android.util.TypedValue.TYPE_INT_DEC; 541756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Guptaimport static android.util.TypedValue.TYPE_INT_HEX; 551756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Guptaimport static android.util.TypedValue.TYPE_NULL; 561756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Guptaimport static android.util.TypedValue.TYPE_REFERENCE; 571756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Guptaimport static android.util.TypedValue.TYPE_STRING; 581756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Guptaimport static com.android.SdkConstants.PREFIX_RESOURCE_REF; 591756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Guptaimport static com.android.SdkConstants.PREFIX_THEME_REF; 601756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Guptaimport static com.android.ide.common.rendering.api.RenderResources.REFERENCE_EMPTY; 611756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Guptaimport static com.android.ide.common.rendering.api.RenderResources.REFERENCE_NULL; 621756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Guptaimport static com.android.ide.common.rendering.api.RenderResources.REFERENCE_UNDEFINED; 636f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta 64ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski/** 65ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Custom implementation of TypedArray to handle non compiled resources. 66ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 67ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskipublic final class BridgeTypedArray extends TypedArray { 68ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 69896eb1c37f6a44d65d3a459891475e99170b657cDeepanshu Gupta private final Resources mBridgeResources; 70ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private final BridgeContext mContext; 71ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski private final boolean mPlatformFile; 72ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 73bc876628ee6b96164b91908ff62fcaefe930f403Charlie Tsai private final int[] mResourceId; 7428948de70d6f77f80b475926c2b88f55e1365ff4Deepanshu Gupta private final ResourceValue[] mResourceData; 7528948de70d6f77f80b475926c2b88f55e1365ff4Deepanshu Gupta private final String[] mNames; 7628948de70d6f77f80b475926c2b88f55e1365ff4Deepanshu Gupta private final boolean[] mIsFramework; 77ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 786f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta // Contains ids that are @empty. We still store null in mResourceData for that index, since we 796f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta // want to save on the check against empty, each time a resource value is requested. 806f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta @Nullable 816f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta private int[] mEmptyIds; 826f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta 83896eb1c37f6a44d65d3a459891475e99170b657cDeepanshu Gupta public BridgeTypedArray(Resources resources, BridgeContext context, int len, 84ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski boolean platformFile) { 85a73a0143fefc62be1ef270db0363272cb4e1864dJohn Reck super(resources); 86ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mBridgeResources = resources; 87ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mContext = context; 88ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mPlatformFile = platformFile; 89bc876628ee6b96164b91908ff62fcaefe930f403Charlie Tsai mResourceId = new int[len]; 90ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mResourceData = new ResourceValue[len]; 91ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mNames = new String[len]; 92ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mIsFramework = new boolean[len]; 93ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 94ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 95ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 96ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * A bridge-specific method that sets a value in the type array 97ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param index the index of the value in the TypedArray 98ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param name the name of the attribute 99ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param isFramework whether the attribute is in the android namespace. 100bc876628ee6b96164b91908ff62fcaefe930f403Charlie Tsai * @param resourceId the reference id of this resource 101ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param value the value of the attribute 102ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 103bc876628ee6b96164b91908ff62fcaefe930f403Charlie Tsai public void bridgeSetValue(int index, String name, boolean isFramework, int resourceId, 104bc876628ee6b96164b91908ff62fcaefe930f403Charlie Tsai ResourceValue value) { 105bc876628ee6b96164b91908ff62fcaefe930f403Charlie Tsai mResourceId[index] = resourceId; 106ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mResourceData[index] = value; 107ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mNames[index] = name; 108ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mIsFramework[index] = isFramework; 109ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 110ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 111ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 11228948de70d6f77f80b475926c2b88f55e1365ff4Deepanshu Gupta * Seals the array after all calls to 113bc876628ee6b96164b91908ff62fcaefe930f403Charlie Tsai * {@link #bridgeSetValue(int, String, boolean, int, ResourceValue)} have been done. 114ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * <p/>This allows to compute the list of non default values, permitting 115ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * {@link #getIndexCount()} to return the proper value. 116ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 117ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void sealArray() { 118ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // fills TypedArray.mIndices which is used to implement getIndexCount/getIndexAt 119ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // first count the array size 120ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski int count = 0; 1216f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta ArrayList<Integer> emptyIds = null; 122d0cf227ef57e88fa9e104ea1dd2f7fa0555adbddDeepanshu Gupta for (int i = 0; i < mResourceData.length; i++) { 123d0cf227ef57e88fa9e104ea1dd2f7fa0555adbddDeepanshu Gupta ResourceValue data = mResourceData[i]; 124d0cf227ef57e88fa9e104ea1dd2f7fa0555adbddDeepanshu Gupta if (data != null) { 1256f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta String dataValue = data.getValue(); 1266f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta if (REFERENCE_NULL.equals(dataValue) || REFERENCE_UNDEFINED.equals(dataValue)) { 1276f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta mResourceData[i] = null; 1286f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta } else if (REFERENCE_EMPTY.equals(dataValue)) { 129d0cf227ef57e88fa9e104ea1dd2f7fa0555adbddDeepanshu Gupta mResourceData[i] = null; 1306f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta if (emptyIds == null) { 1316f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta emptyIds = new ArrayList<Integer>(4); 1326f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta } 1336f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta emptyIds.add(i); 134d0cf227ef57e88fa9e104ea1dd2f7fa0555adbddDeepanshu Gupta } else { 135d0cf227ef57e88fa9e104ea1dd2f7fa0555adbddDeepanshu Gupta count++; 136d0cf227ef57e88fa9e104ea1dd2f7fa0555adbddDeepanshu Gupta } 137ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 138ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 139ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 1406f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta if (emptyIds != null) { 1416f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta mEmptyIds = new int[emptyIds.size()]; 1426f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta for (int i = 0; i < emptyIds.size(); i++) { 1436f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta mEmptyIds[i] = emptyIds.get(i); 1446f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta } 1456f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta } 1466f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta 147ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // allocate the table with an extra to store the size 148ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mIndices = new int[count+1]; 149ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mIndices[0] = count; 150ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 151ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // fill the array with the indices. 152ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski int index = 1; 153ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski for (int i = 0 ; i < mResourceData.length ; i++) { 154d0cf227ef57e88fa9e104ea1dd2f7fa0555adbddDeepanshu Gupta if (mResourceData[i] != null) { 155ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski mIndices[index++] = i; 156ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 157ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 158ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 159ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 160ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 161ca617d8a82e46474f597fe9a9b13bf0abc89f0baDeepanshu Gupta * Set the theme to be used for inflating drawables. 162ca617d8a82e46474f597fe9a9b13bf0abc89f0baDeepanshu Gupta */ 163ca617d8a82e46474f597fe9a9b13bf0abc89f0baDeepanshu Gupta public void setTheme(Theme theme) { 164ca617d8a82e46474f597fe9a9b13bf0abc89f0baDeepanshu Gupta mTheme = theme; 165ca617d8a82e46474f597fe9a9b13bf0abc89f0baDeepanshu Gupta } 166ca617d8a82e46474f597fe9a9b13bf0abc89f0baDeepanshu Gupta 167ca617d8a82e46474f597fe9a9b13bf0abc89f0baDeepanshu Gupta /** 168ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Return the number of values in this array. 169ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 170ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 171ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public int length() { 172ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return mResourceData.length; 173ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 174ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 175ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 176ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Return the Resources object this array was loaded from. 177ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 178ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 179ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public Resources getResources() { 180ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return mBridgeResources; 181ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 182ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 183ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 184ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Retrieve the styled string value for the attribute at <var>index</var>. 185ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 186ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param index Index of attribute to retrieve. 187ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 188ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return CharSequence holding string data. May be styled. Returns 189ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * null if the attribute is not defined. 190ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 191ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 192ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public CharSequence getText(int index) { 19332645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta // FIXME: handle styled strings! 19432645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta return getString(index); 195ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 196ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 197ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 198ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Retrieve the string value for the attribute at <var>index</var>. 199ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 200ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param index Index of attribute to retrieve. 201ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 202ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return String holding string data. Any styling information is 203ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * removed. Returns null if the attribute is not defined. 204ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 205ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 206ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public String getString(int index) { 20732645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta if (!hasValue(index)) { 208ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return null; 209ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 21032645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta // As unfortunate as it is, it's possible to use enums with all attribute formats, 211e77c203bd64b0d4a846e9d9e2155b6238620009dDeepanshu Gupta // not just integers/enums. So, we need to search the enums always. In case 21232645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta // enums are used, the returned value is an integer. 21332645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta Integer v = resolveEnumAttribute(index); 21432645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta return v == null ? mResourceData[index].getValue() : String.valueOf((int) v); 215ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 216ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 217ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 218ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Retrieve the boolean value for the attribute at <var>index</var>. 219ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 220ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param index Index of attribute to retrieve. 221ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param defValue Value to return if the attribute is not defined. 222ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 223ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return Attribute boolean value, or defValue if not defined. 224ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 225ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 226ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public boolean getBoolean(int index, boolean defValue) { 22732645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta String s = getString(index); 22832645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta return s == null ? defValue : XmlUtils.convertValueToBoolean(s, defValue); 229ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 230ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 231ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 232ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 233ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Retrieve the integer value for the attribute at <var>index</var>. 234ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 235ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param index Index of attribute to retrieve. 236ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param defValue Value to return if the attribute is not defined. 237ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 238ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return Attribute int value, or defValue if not defined. 239ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 240ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 241ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public int getInt(int index, int defValue) { 24232645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta String s = getString(index); 243ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski try { 244b7a03c66dfbfed6ce8197b1fbc2aec8925bc410cDeepanshu Gupta return convertValueToInt(s, defValue); 24532645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta } catch (NumberFormatException e) { 24632645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, 247e77c203bd64b0d4a846e9d9e2155b6238620009dDeepanshu Gupta String.format("\"%1$s\" in attribute \"%2$s\" is not a valid integer", 24832645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta s, mNames[index]), 24932645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta null); 250ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 251ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return defValue; 252ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 253ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 254ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 255ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Retrieve the float value for the attribute at <var>index</var>. 256ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 257ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param index Index of attribute to retrieve. 258ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 259ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return Attribute float value, or defValue if not defined.. 260ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 261ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 262ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public float getFloat(int index, float defValue) { 26332645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta String s = getString(index); 26432645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta try { 26532645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta if (s != null) { 26632645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta return Float.parseFloat(s); 267ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 26832645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta } catch (NumberFormatException e) { 26932645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, 270e77c203bd64b0d4a846e9d9e2155b6238620009dDeepanshu Gupta String.format("\"%1$s\" in attribute \"%2$s\" cannot be converted to float.", 27132645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta s, mNames[index]), 27232645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta null); 273ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 274ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return defValue; 275ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 276ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 277ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 278ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Retrieve the color value for the attribute at <var>index</var>. If 279ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * the attribute references a color resource holding a complex 280ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * {@link android.content.res.ColorStateList}, then the default color from 281ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * the set is returned. 282ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 283ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param index Index of attribute to retrieve. 284ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param defValue Value to return if the attribute is not defined or 285ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * not a resource. 286ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 287ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return Attribute color value, or defValue if not defined. 288ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 289ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 290ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public int getColor(int index, int defValue) { 291ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (index < 0 || index >= mResourceData.length) { 292ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return defValue; 293ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 294ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 295ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (mResourceData[index] == null) { 296ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return defValue; 297ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 298ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 299ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski ColorStateList colorStateList = ResourceHelper.getColorStateList( 3005fe96f847cc6b35510cd6e97777c8b8b75d94671Diego Perez mResourceData[index], mContext, mTheme); 301ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (colorStateList != null) { 302ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return colorStateList.getDefaultColor(); 303ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 304ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 305ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return defValue; 306ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 307ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 308e4cf18face6980b0c7ac42761512cd93b89927c3Diego Perez @Override 309ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public ColorStateList getColorStateList(int index) { 31032645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta if (!hasValue(index)) { 311ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return null; 312ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 313ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 3145fe96f847cc6b35510cd6e97777c8b8b75d94671Diego Perez return ResourceHelper.getColorStateList(mResourceData[index], mContext, mTheme); 315741ef6aac95e239f894f5640b8ff9728655e98b7Diego Perez } 316129839107b12d1d42ce53a2b7ed0895589b59ff6Jerome Gaillard 317741ef6aac95e239f894f5640b8ff9728655e98b7Diego Perez @Override 318741ef6aac95e239f894f5640b8ff9728655e98b7Diego Perez public ComplexColor getComplexColor(int index) { 319741ef6aac95e239f894f5640b8ff9728655e98b7Diego Perez if (!hasValue(index)) { 320129839107b12d1d42ce53a2b7ed0895589b59ff6Jerome Gaillard return null; 321ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 322ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 3235fe96f847cc6b35510cd6e97777c8b8b75d94671Diego Perez return ResourceHelper.getComplexColor(mResourceData[index], mContext, mTheme); 324ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 325ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 326ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 327ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Retrieve the integer value for the attribute at <var>index</var>. 328ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 329ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param index Index of attribute to retrieve. 330ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param defValue Value to return if the attribute is not defined or 331ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * not a resource. 332ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 333ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return Attribute integer value, or defValue if not defined. 334ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 335ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 336ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public int getInteger(int index, int defValue) { 337ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return getInt(index, defValue); 338ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 339ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 340ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 341ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Retrieve a dimensional unit attribute at <var>index</var>. Unit 342ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * conversions are based on the current {@link DisplayMetrics} 343ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * associated with the resources this {@link TypedArray} object 344ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * came from. 345ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 346ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param index Index of attribute to retrieve. 347ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param defValue Value to return if the attribute is not defined or 348ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * not a resource. 349ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 350ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return Attribute dimension value multiplied by the appropriate 351ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * metric, or defValue if not defined. 352ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 353ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @see #getDimensionPixelOffset 354ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @see #getDimensionPixelSize 355ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 356ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 357ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public float getDimension(int index, float defValue) { 35832645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta String s = getString(index); 359ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (s == null) { 360ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return defValue; 361ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 36232645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta // Check if the value is a magic constant that doesn't require a unit. 36332645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta try { 36432645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta int i = Integer.parseInt(s); 36532645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta if (i == LayoutParams.MATCH_PARENT || i == LayoutParams.WRAP_CONTENT) { 36632645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta return i; 36732645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta } 36832645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta } catch (NumberFormatException ignored) { 36932645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta // pass 37032645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta } 371ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 372d0cf227ef57e88fa9e104ea1dd2f7fa0555adbddDeepanshu Gupta if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) { 373ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return mValue.getDimension(mBridgeResources.getDisplayMetrics()); 374ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 375ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 37632645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta return defValue; 377ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 378ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 379ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 380ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Retrieve a dimensional unit attribute at <var>index</var> for use 381ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * as an offset in raw pixels. This is the same as 382ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * {@link #getDimension}, except the returned value is converted to 383ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * integer pixels for you. An offset conversion involves simply 384ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * truncating the base value to an integer. 385ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 386ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param index Index of attribute to retrieve. 387ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param defValue Value to return if the attribute is not defined or 388ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * not a resource. 389ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 390ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return Attribute dimension value multiplied by the appropriate 391ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * metric and truncated to integer pixels, or defValue if not defined. 392ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 393ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @see #getDimension 394ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @see #getDimensionPixelSize 395ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 396ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 397ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public int getDimensionPixelOffset(int index, int defValue) { 398ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return (int) getDimension(index, defValue); 399ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 400ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 401ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 402ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Retrieve a dimensional unit attribute at <var>index</var> for use 403ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * as a size in raw pixels. This is the same as 404ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * {@link #getDimension}, except the returned value is converted to 405ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * integer pixels for use as a size. A size conversion involves 406ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * rounding the base value, and ensuring that a non-zero base value 407ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * is at least one pixel in size. 408ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 409ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param index Index of attribute to retrieve. 410ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param defValue Value to return if the attribute is not defined or 411ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * not a resource. 412ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 413ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return Attribute dimension value multiplied by the appropriate 414ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * metric and truncated to integer pixels, or defValue if not defined. 415ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 416ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @see #getDimension 417ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @see #getDimensionPixelOffset 418ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 419ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 420ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public int getDimensionPixelSize(int index, int defValue) { 421ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski try { 422a9d1c5b4e2bd54b0e77c817b0813bec6cddc0eacDeepanshu Gupta return getDimension(index, null); 423ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } catch (RuntimeException e) { 42432645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta String s = getString(index); 42532645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta 42632645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta if (s != null) { 42732645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta // looks like we were unable to resolve the dimension value 42832645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, 42932645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta String.format("\"%1$s\" in attribute \"%2$s\" is not a valid format.", 430d0cf227ef57e88fa9e104ea1dd2f7fa0555adbddDeepanshu Gupta s, mNames[index]), null); 431ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 432ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 433ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return defValue; 434ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 435ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 436ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 437ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 438ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Special version of {@link #getDimensionPixelSize} for retrieving 439ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * {@link android.view.ViewGroup}'s layout_width and layout_height 440ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * attributes. This is only here for performance reasons; applications 441ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * should use {@link #getDimensionPixelSize}. 442ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 443ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param index Index of the attribute to retrieve. 444ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param name Textual name of attribute for error reporting. 445ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 446ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return Attribute dimension value multiplied by the appropriate 447ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * metric and truncated to integer pixels. 448ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 449ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 450ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public int getLayoutDimension(int index, String name) { 451ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski try { 452a9d1c5b4e2bd54b0e77c817b0813bec6cddc0eacDeepanshu Gupta // this will throw an exception if not found. 453a9d1c5b4e2bd54b0e77c817b0813bec6cddc0eacDeepanshu Gupta return getDimension(index, name); 454ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } catch (RuntimeException e) { 455ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 456ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (LayoutInflater_Delegate.sIsInInclude) { 457a9d1c5b4e2bd54b0e77c817b0813bec6cddc0eacDeepanshu Gupta throw new RuntimeException("Layout Dimension '" + name + "' not found."); 458ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 459ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 460ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, 461ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski "You must supply a " + name + " attribute.", null); 462ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 463ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return 0; 464ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 465ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 466ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 467ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 468ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public int getLayoutDimension(int index, int defValue) { 469ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return getDimensionPixelSize(index, defValue); 470ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 471ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 472a9d1c5b4e2bd54b0e77c817b0813bec6cddc0eacDeepanshu Gupta /** @param name attribute name, used for error reporting. */ 473a9d1c5b4e2bd54b0e77c817b0813bec6cddc0eacDeepanshu Gupta private int getDimension(int index, @Nullable String name) { 47432645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta String s = getString(index); 475ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (s == null) { 476a9d1c5b4e2bd54b0e77c817b0813bec6cddc0eacDeepanshu Gupta if (name != null) { 477a9d1c5b4e2bd54b0e77c817b0813bec6cddc0eacDeepanshu Gupta throw new RuntimeException("Attribute '" + name + "' not found"); 478a9d1c5b4e2bd54b0e77c817b0813bec6cddc0eacDeepanshu Gupta } 479ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski throw new RuntimeException(); 480ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 48132645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta // Check if the value is a magic constant that doesn't require a unit. 48232645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta try { 48332645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta int i = Integer.parseInt(s); 48432645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta if (i == LayoutParams.MATCH_PARENT || i == LayoutParams.WRAP_CONTENT) { 48532645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta return i; 48632645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta } 48732645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta } catch (NumberFormatException ignored) { 48832645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta // pass 48932645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta } 490d0cf227ef57e88fa9e104ea1dd2f7fa0555adbddDeepanshu Gupta if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) { 491ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski float f = mValue.getDimension(mBridgeResources.getDisplayMetrics()); 492ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 493ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski final int res = (int)(f+0.5f); 494ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (res != 0) return res; 495ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (f == 0) return 0; 496ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (f > 0) return 1; 497ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 498ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 499ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski throw new RuntimeException(); 500ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 501ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 502ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 503ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Retrieve a fractional unit attribute at <var>index</var>. 504ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 505ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param index Index of attribute to retrieve. 506ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param base The base value of this fraction. In other words, a 507ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * standard fraction is multiplied by this value. 508ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param pbase The parent base value of this fraction. In other 509ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * words, a parent fraction (nn%p) is multiplied by this 510ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * value. 511ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param defValue Value to return if the attribute is not defined or 512ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * not a resource. 513ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 514ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return Attribute fractional value multiplied by the appropriate 515ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * base value, or defValue if not defined. 516ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 517ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 518ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public float getFraction(int index, int base, int pbase, float defValue) { 51932645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta String value = getString(index); 520ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (value == null) { 521ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return defValue; 522ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 523ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 524d0cf227ef57e88fa9e104ea1dd2f7fa0555adbddDeepanshu Gupta if (ResourceHelper.parseFloatAttribute(mNames[index], value, mValue, false)) { 525ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return mValue.getFraction(base, pbase); 526ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 527ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 528ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // looks like we were unable to resolve the fraction value 529ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, 530ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski String.format( 531d0cf227ef57e88fa9e104ea1dd2f7fa0555adbddDeepanshu Gupta "\"%1$s\" in attribute \"%2$s\" cannot be converted to a fraction.", 532d0cf227ef57e88fa9e104ea1dd2f7fa0555adbddDeepanshu Gupta value, mNames[index]), null); 533ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 534ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return defValue; 535ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 536ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 537ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 538ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Retrieve the resource identifier for the attribute at 539ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * <var>index</var>. Note that attribute resource as resolved when 540ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * the overall {@link TypedArray} object is retrieved. As a 541ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * result, this function will return the resource identifier of the 542ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * final resource value that was found, <em>not</em> necessarily the 543ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * original resource that was specified by the attribute. 544ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 545ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param index Index of attribute to retrieve. 546ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param defValue Value to return if the attribute is not defined or 547ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * not a resource. 548ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 549ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return Attribute resource identifier, or defValue if not defined. 550ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 551ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 552ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public int getResourceId(int index, int defValue) { 553ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (index < 0 || index >= mResourceData.length) { 554ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return defValue; 555ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 556ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 557ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // get the Resource for this index 558ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski ResourceValue resValue = mResourceData[index]; 559ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 560ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // no data, return the default value. 561ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (resValue == null) { 562ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return defValue; 563ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 564ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 565ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // check if this is a style resource 566ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (resValue instanceof StyleResourceValue) { 567ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // get the id that will represent this style. 568ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return mContext.getDynamicIdByStyle((StyleResourceValue)resValue); 569ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 570ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 571ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // if the attribute was a reference to a resource, and not a declaration of an id (@+id), 572ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // then the xml attribute value was "resolved" which leads us to a ResourceValue with a 573ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // valid getType() and getName() returning a resource name. 574ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // (and getValue() returning null!). We need to handle this! 575ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (resValue.getResourceType() != null) { 576ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // if this is a framework id 577ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (mPlatformFile || resValue.isFramework()) { 578ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // look for idName in the android R classes 579ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return mContext.getFrameworkResourceValue( 580ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski resValue.getResourceType(), resValue.getName(), defValue); 581ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 582ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 583ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // look for idName in the project R class. 584ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return mContext.getProjectResourceValue( 585ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski resValue.getResourceType(), resValue.getName(), defValue); 586ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 587ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 588ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // else, try to get the value, and resolve it somehow. 589ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski String value = resValue.getValue(); 590ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (value == null) { 591ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return defValue; 592ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 5939b30e13d8a9896da848fb5db5f91c802fc5249b2Diego Perez value = value.trim(); 594ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 595ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // if the value is just an integer, return it. 596ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski try { 597ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski int i = Integer.parseInt(value); 598ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (Integer.toString(i).equals(value)) { 599ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return i; 600ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 601ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } catch (NumberFormatException e) { 602ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass 603ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 604ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 6059b30e13d8a9896da848fb5db5f91c802fc5249b2Diego Perez if (value.startsWith("#")) { 6069b30e13d8a9896da848fb5db5f91c802fc5249b2Diego Perez // this looks like a color, do not try to parse it 6079b30e13d8a9896da848fb5db5f91c802fc5249b2Diego Perez return defValue; 6089b30e13d8a9896da848fb5db5f91c802fc5249b2Diego Perez } 6099b30e13d8a9896da848fb5db5f91c802fc5249b2Diego Perez 610ef221c3b4f85123ac1ba21b46e36545c91508edaDiego Perez if (Typeface_Accessor.isSystemFont(value)) { 611ef221c3b4f85123ac1ba21b46e36545c91508edaDiego Perez // A system font family value, do not try to parse 612ef221c3b4f85123ac1ba21b46e36545c91508edaDiego Perez return defValue; 613ef221c3b4f85123ac1ba21b46e36545c91508edaDiego Perez } 614ef221c3b4f85123ac1ba21b46e36545c91508edaDiego Perez 615ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // Handle the @id/<name>, @+id/<name> and @android:id/<name> 616ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // We need to return the exact value that was compiled (from the various R classes), 617ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // as these values can be reused internally with calls to findViewById(). 618ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // There's a trick with platform layouts that not use "android:" but their IDs are in 619ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // fact in the android.R and com.android.internal.R classes. 620ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // The field mPlatformFile will indicate that all IDs are to be looked up in the android R 621ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // classes exclusively. 622ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 623ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // if this is a reference to an id, find it. 624ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (value.startsWith("@id/") || value.startsWith("@+") || 625ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski value.startsWith("@android:id/")) { 626ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 627ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski int pos = value.indexOf('/'); 628ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski String idName = value.substring(pos + 1); 629c8a55f3e2e36475d8a86a5967a9f2db629e02d1cDeepanshu Gupta boolean create = value.startsWith("@+"); 630c8a55f3e2e36475d8a86a5967a9f2db629e02d1cDeepanshu Gupta boolean isFrameworkId = 631c8a55f3e2e36475d8a86a5967a9f2db629e02d1cDeepanshu Gupta mPlatformFile || value.startsWith("@android") || value.startsWith("@+android"); 632c8a55f3e2e36475d8a86a5967a9f2db629e02d1cDeepanshu Gupta 633c8a55f3e2e36475d8a86a5967a9f2db629e02d1cDeepanshu Gupta // Look for the idName in project or android R class depending on isPlatform. 634c8a55f3e2e36475d8a86a5967a9f2db629e02d1cDeepanshu Gupta if (create) { 635c8a55f3e2e36475d8a86a5967a9f2db629e02d1cDeepanshu Gupta Integer idValue; 636c8a55f3e2e36475d8a86a5967a9f2db629e02d1cDeepanshu Gupta if (isFrameworkId) { 637c8a55f3e2e36475d8a86a5967a9f2db629e02d1cDeepanshu Gupta idValue = Bridge.getResourceId(ResourceType.ID, idName); 638c8a55f3e2e36475d8a86a5967a9f2db629e02d1cDeepanshu Gupta } else { 639b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta idValue = mContext.getLayoutlibCallback().getResourceId(ResourceType.ID, idName); 640c8a55f3e2e36475d8a86a5967a9f2db629e02d1cDeepanshu Gupta } 641c8a55f3e2e36475d8a86a5967a9f2db629e02d1cDeepanshu Gupta return idValue == null ? defValue : idValue; 642c8a55f3e2e36475d8a86a5967a9f2db629e02d1cDeepanshu Gupta } 643c8a55f3e2e36475d8a86a5967a9f2db629e02d1cDeepanshu Gupta // This calls the same method as in if(create), but doesn't create a dynamic id, if 644c8a55f3e2e36475d8a86a5967a9f2db629e02d1cDeepanshu Gupta // one is not found. 645c8a55f3e2e36475d8a86a5967a9f2db629e02d1cDeepanshu Gupta if (isFrameworkId) { 646ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return mContext.getFrameworkResourceValue(ResourceType.ID, idName, defValue); 647c8a55f3e2e36475d8a86a5967a9f2db629e02d1cDeepanshu Gupta } else { 648c8a55f3e2e36475d8a86a5967a9f2db629e02d1cDeepanshu Gupta return mContext.getProjectResourceValue(ResourceType.ID, idName, defValue); 649ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 650ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 651e76383f79ff4e9103857c94a1fc16afb34587540Diego Perez else if (value.startsWith("@aapt:_aapt")) { 652e76383f79ff4e9103857c94a1fc16afb34587540Diego Perez return mContext.getLayoutlibCallback().getResourceId(ResourceType.AAPT, value); 653e76383f79ff4e9103857c94a1fc16afb34587540Diego Perez } 654ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 65521bf7d189aea4c63a03716a4e82f4193f099e7eeDiego Perez // not a direct id valid reference. First check if it's an enum (this is a corner case 65621bf7d189aea4c63a03716a4e82f4193f099e7eeDiego Perez // for attributes that have a reference|enum type), then fallback to resolve 65721bf7d189aea4c63a03716a4e82f4193f099e7eeDiego Perez // as an ID without prefix. 65821bf7d189aea4c63a03716a4e82f4193f099e7eeDiego Perez Integer enumValue = resolveEnumAttribute(index); 65921bf7d189aea4c63a03716a4e82f4193f099e7eeDiego Perez if (enumValue != null) { 66021bf7d189aea4c63a03716a4e82f4193f099e7eeDiego Perez return enumValue; 66121bf7d189aea4c63a03716a4e82f4193f099e7eeDiego Perez } 66221bf7d189aea4c63a03716a4e82f4193f099e7eeDiego Perez 66321bf7d189aea4c63a03716a4e82f4193f099e7eeDiego Perez // Ok, not an enum, resolve as an ID 66428948de70d6f77f80b475926c2b88f55e1365ff4Deepanshu Gupta Integer idValue; 665ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 666ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (resValue.isFramework()) { 667ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski idValue = Bridge.getResourceId(resValue.getResourceType(), 668ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski resValue.getName()); 669ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } else { 670b111e84752652ec862efa7e0fcaa224430feb97fDeepanshu Gupta idValue = mContext.getLayoutlibCallback().getResourceId( 671ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski resValue.getResourceType(), resValue.getName()); 672ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 673ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 674ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (idValue != null) { 67528948de70d6f77f80b475926c2b88f55e1365ff4Deepanshu Gupta return idValue; 676ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 677ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 67871b8fa8301051c0678fbaa79edd7ba884047df4fJerome Gaillard if ("text".equals(mNames[index])) { 67971b8fa8301051c0678fbaa79edd7ba884047df4fJerome Gaillard // In a TextView, if the text is set from the attribute android:text, the correct 68071b8fa8301051c0678fbaa79edd7ba884047df4fJerome Gaillard // behaviour is not to find a resourceId for the text, and to return the default value. 68171b8fa8301051c0678fbaa79edd7ba884047df4fJerome Gaillard // So in this case, do not log a warning. 68271b8fa8301051c0678fbaa79edd7ba884047df4fJerome Gaillard return defValue; 68371b8fa8301051c0678fbaa79edd7ba884047df4fJerome Gaillard } 68471b8fa8301051c0678fbaa79edd7ba884047df4fJerome Gaillard 685ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_RESOLVE, 686ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski String.format( 687ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski "Unable to resolve id \"%1$s\" for attribute \"%2$s\"", value, mNames[index]), 688ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski resValue); 689ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 690ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return defValue; 691ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 692ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 69328948de70d6f77f80b475926c2b88f55e1365ff4Deepanshu Gupta @Override 69428948de70d6f77f80b475926c2b88f55e1365ff4Deepanshu Gupta public int getThemeAttributeId(int index, int defValue) { 69528948de70d6f77f80b475926c2b88f55e1365ff4Deepanshu Gupta // TODO: Get the right Theme Attribute ID to enable caching of the drawables. 69628948de70d6f77f80b475926c2b88f55e1365ff4Deepanshu Gupta return defValue; 69728948de70d6f77f80b475926c2b88f55e1365ff4Deepanshu Gupta } 69828948de70d6f77f80b475926c2b88f55e1365ff4Deepanshu Gupta 699ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 700ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Retrieve the Drawable for the attribute at <var>index</var>. This 701ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * gets the resource ID of the selected attribute, and uses 702ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * {@link Resources#getDrawable Resources.getDrawable} of the owning 703ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Resources object to retrieve its Drawable. 704ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 705ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param index Index of attribute to retrieve. 706ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 707ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return Drawable for the attribute, or null if not defined. 708ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 709ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 710ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public Drawable getDrawable(int index) { 71132645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta if (!hasValue(index)) { 712ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return null; 713ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 714ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 715ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski ResourceValue value = mResourceData[index]; 716ca617d8a82e46474f597fe9a9b13bf0abc89f0baDeepanshu Gupta return ResourceHelper.getDrawable(value, mContext, mTheme); 717ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 718ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 71941599e719d17f7a7fb64e2df043eb3542f4325f5Diego Perez /** 72041599e719d17f7a7fb64e2df043eb3542f4325f5Diego Perez * Version of {@link #getDrawable(int)} that accepts an override density. 72141599e719d17f7a7fb64e2df043eb3542f4325f5Diego Perez * @hide 72241599e719d17f7a7fb64e2df043eb3542f4325f5Diego Perez */ 72341599e719d17f7a7fb64e2df043eb3542f4325f5Diego Perez @Override 72441599e719d17f7a7fb64e2df043eb3542f4325f5Diego Perez public Drawable getDrawableForDensity(int index, int density) { 72541599e719d17f7a7fb64e2df043eb3542f4325f5Diego Perez return getDrawable(index); 72641599e719d17f7a7fb64e2df043eb3542f4325f5Diego Perez } 727ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 728ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 7297c22a707de1ed939ebd91079dff9df6cd5ffd401Diego Perez * Retrieve the Typeface for the attribute at <var>index</var>. 7307c22a707de1ed939ebd91079dff9df6cd5ffd401Diego Perez * @param index Index of attribute to retrieve. 7317c22a707de1ed939ebd91079dff9df6cd5ffd401Diego Perez * 7327c22a707de1ed939ebd91079dff9df6cd5ffd401Diego Perez * @return Typeface for the attribute, or null if not defined. 7337c22a707de1ed939ebd91079dff9df6cd5ffd401Diego Perez */ 7347c22a707de1ed939ebd91079dff9df6cd5ffd401Diego Perez @Override 7357c22a707de1ed939ebd91079dff9df6cd5ffd401Diego Perez public Typeface getFont(int index) { 7367c22a707de1ed939ebd91079dff9df6cd5ffd401Diego Perez if (!hasValue(index)) { 7377c22a707de1ed939ebd91079dff9df6cd5ffd401Diego Perez return null; 7387c22a707de1ed939ebd91079dff9df6cd5ffd401Diego Perez } 7397c22a707de1ed939ebd91079dff9df6cd5ffd401Diego Perez 7407c22a707de1ed939ebd91079dff9df6cd5ffd401Diego Perez ResourceValue value = mResourceData[index]; 7417c22a707de1ed939ebd91079dff9df6cd5ffd401Diego Perez return ResourceHelper.getFont(value, mContext, mTheme); 7427c22a707de1ed939ebd91079dff9df6cd5ffd401Diego Perez } 7437c22a707de1ed939ebd91079dff9df6cd5ffd401Diego Perez 7447c22a707de1ed939ebd91079dff9df6cd5ffd401Diego Perez /** 745ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Retrieve the CharSequence[] for the attribute at <var>index</var>. 746ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * This gets the resource ID of the selected attribute, and uses 747ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * {@link Resources#getTextArray Resources.getTextArray} of the owning 748ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Resources object to retrieve its String[]. 749ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 750ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param index Index of attribute to retrieve. 751ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 752ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return CharSequence[] for the attribute, or null if not defined. 753ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 754ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 755ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public CharSequence[] getTextArray(int index) { 75637e93696222aed44026f6423dd05ebc7c3c72b71Deepanshu Gupta if (!hasValue(index)) { 75737e93696222aed44026f6423dd05ebc7c3c72b71Deepanshu Gupta return null; 758ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 75937e93696222aed44026f6423dd05ebc7c3c72b71Deepanshu Gupta ResourceValue resVal = mResourceData[index]; 76037e93696222aed44026f6423dd05ebc7c3c72b71Deepanshu Gupta if (resVal instanceof ArrayResourceValue) { 76137e93696222aed44026f6423dd05ebc7c3c72b71Deepanshu Gupta ArrayResourceValue array = (ArrayResourceValue) resVal; 76237e93696222aed44026f6423dd05ebc7c3c72b71Deepanshu Gupta int count = array.getElementCount(); 763896eb1c37f6a44d65d3a459891475e99170b657cDeepanshu Gupta return count >= 0 ? Resources_Delegate.fillValues(mBridgeResources, array, new CharSequence[count]) : 764896eb1c37f6a44d65d3a459891475e99170b657cDeepanshu Gupta null; 76537e93696222aed44026f6423dd05ebc7c3c72b71Deepanshu Gupta } 76637e93696222aed44026f6423dd05ebc7c3c72b71Deepanshu Gupta int id = getResourceId(index, 0); 76737e93696222aed44026f6423dd05ebc7c3c72b71Deepanshu Gupta String resIdMessage = id > 0 ? " (resource id 0x" + Integer.toHexString(id) + ')' : ""; 7680609785e6f839bfd27e33fa2630e6a1c12be9a20Diego Perez assert false : 7690609785e6f839bfd27e33fa2630e6a1c12be9a20Diego Perez String.format("%1$s in %2$s%3$s is not a valid array resource.", resVal.getValue(), 7700609785e6f839bfd27e33fa2630e6a1c12be9a20Diego Perez mNames[index], resIdMessage); 7710609785e6f839bfd27e33fa2630e6a1c12be9a20Diego Perez 7720609785e6f839bfd27e33fa2630e6a1c12be9a20Diego Perez return new CharSequence[0]; 773ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 774ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 775f0a7a1cb5b3ab8e9f46128c57dd8745e39706fbbDeepanshu Gupta @Override 776f0a7a1cb5b3ab8e9f46128c57dd8745e39706fbbDeepanshu Gupta public int[] extractThemeAttrs() { 777eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta // The drawables are always inflated with a Theme and we don't care about caching. So, 778eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta // just return. 779f0a7a1cb5b3ab8e9f46128c57dd8745e39706fbbDeepanshu Gupta return null; 780f0a7a1cb5b3ab8e9f46128c57dd8745e39706fbbDeepanshu Gupta } 781f0a7a1cb5b3ab8e9f46128c57dd8745e39706fbbDeepanshu Gupta 782eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta @Override 783eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta public int getChangingConfigurations() { 784eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta // We don't care about caching. Any change in configuration is a fresh render. So, 785eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta // just return. 786eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta return 0; 787eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta } 788eeb44a29846ac0d36a1fad1b6869e932d1dc01ceDeepanshu Gupta 789ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 790ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Retrieve the raw TypedValue for the attribute at <var>index</var>. 791ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 792ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param index Index of attribute to retrieve. 793ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param outValue TypedValue object in which to place the attribute's 794ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * data. 795ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 796ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return Returns true if the value was retrieved, else false. 797ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 798ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 799ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public boolean getValue(int index, TypedValue outValue) { 8003dd065e62224ca70a8415ebe8764b626f86a9397Charlie Tsai // TODO: more switch cases for other types. 8013dd065e62224ca70a8415ebe8764b626f86a9397Charlie Tsai outValue.type = getType(index); 8023dd065e62224ca70a8415ebe8764b626f86a9397Charlie Tsai switch (outValue.type) { 8033dd065e62224ca70a8415ebe8764b626f86a9397Charlie Tsai case TYPE_NULL: 8043dd065e62224ca70a8415ebe8764b626f86a9397Charlie Tsai return false; 8053dd065e62224ca70a8415ebe8764b626f86a9397Charlie Tsai case TYPE_STRING: 8063dd065e62224ca70a8415ebe8764b626f86a9397Charlie Tsai outValue.string = getString(index); 8073dd065e62224ca70a8415ebe8764b626f86a9397Charlie Tsai return true; 808bc876628ee6b96164b91908ff62fcaefe930f403Charlie Tsai case TYPE_REFERENCE: 809bc876628ee6b96164b91908ff62fcaefe930f403Charlie Tsai outValue.resourceId = mResourceId[index]; 810bc876628ee6b96164b91908ff62fcaefe930f403Charlie Tsai return true; 8113dd065e62224ca70a8415ebe8764b626f86a9397Charlie Tsai default: 8123dd065e62224ca70a8415ebe8764b626f86a9397Charlie Tsai // For back-compatibility, parse as float. 8133dd065e62224ca70a8415ebe8764b626f86a9397Charlie Tsai String s = getString(index); 8143dd065e62224ca70a8415ebe8764b626f86a9397Charlie Tsai return s != null && 8153dd065e62224ca70a8415ebe8764b626f86a9397Charlie Tsai ResourceHelper.parseFloatAttribute(mNames[index], s, outValue, false); 8163dd065e62224ca70a8415ebe8764b626f86a9397Charlie Tsai } 817ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 818ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 8199fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta @Override 8201756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta @SuppressWarnings("ResultOfMethodCallIgnored") 8219fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta public int getType(int index) { 8221756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta String value = getString(index); 8231756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta if (value == null) { 8241756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta return TYPE_NULL; 8259fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta } 8261756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta if (value.startsWith(PREFIX_RESOURCE_REF)) { 8271756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta return TYPE_REFERENCE; 8281756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } 8291756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta if (value.startsWith(PREFIX_THEME_REF)) { 8301756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta return TYPE_ATTRIBUTE; 8311756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } 8321756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta try { 8331756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta // Don't care about the value. Only called to check if an exception is thrown. 8341756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta convertValueToInt(value, 0); 8351756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta if (value.startsWith("0x") || value.startsWith("0X")) { 8361756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta return TYPE_INT_HEX; 8371756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } 8381756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta // is it a color? 8391756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta if (value.startsWith("#")) { 8401756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta int length = value.length() - 1; 8411756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta if (length == 3) { // rgb 8421756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta return TYPE_INT_COLOR_RGB4; 8431756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } 8441756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta if (length == 4) { // argb 8451756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta return TYPE_INT_COLOR_ARGB4; 8461756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } 8471756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta if (length == 6) { // rrggbb 8481756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta return TYPE_INT_COLOR_RGB8; 8491756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } 8501756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta if (length == 8) { // aarrggbb 8511756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta return TYPE_INT_COLOR_ARGB8; 8521756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } 8531756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } 8541756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) { 8551756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta return TYPE_INT_BOOLEAN; 8561756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } 8571756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta return TYPE_INT_DEC; 8581756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } catch (NumberFormatException ignored) { 8591756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta try { 8601756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta Float.parseFloat(value); 8611756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta return TYPE_FLOAT; 8621756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } catch (NumberFormatException ignore) { 8631756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } 8641756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta // Might be a dimension. 8651756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta if (ResourceHelper.parseFloatAttribute(null, value, new TypedValue(), false)) { 8661756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta return TYPE_DIMENSION; 8671756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } 8681756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } 8691756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta // TODO: handle fractions. 8701756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta return TYPE_STRING; 8719fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta } 8729fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta 873ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 874ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Determines whether there is an attribute at <var>index</var>. 875ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 876ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param index Index of attribute to retrieve. 877ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 878ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return True if the attribute has a value, false otherwise. 879ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 880ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 881ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public boolean hasValue(int index) { 88232645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta return index >= 0 && index < mResourceData.length && mResourceData[index] != null; 883ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 884ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 8856f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta @Override 8866f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta public boolean hasValueOrEmpty(int index) { 8876f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta return hasValue(index) || index >= 0 && index < mResourceData.length && 8886f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta mEmptyIds != null && Arrays.binarySearch(mEmptyIds, index) >= 0; 8896f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta } 8906f3ccf0e18239aa6d8d5b352cf7d411f8716e0a7Deepanshu Gupta 891ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 892ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Retrieve the raw TypedValue for the attribute at <var>index</var> 893ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * and return a temporary object holding its data. This object is only 894ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * valid until the next call on to {@link TypedArray}. 895ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 896ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @param index Index of attribute to retrieve. 897ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * 898ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @return Returns a TypedValue object if the attribute is defined, 899ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * containing its data; otherwise returns null. (You will not 900ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * receive a TypedValue whose type is TYPE_NULL.) 901ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 902ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 903ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public TypedValue peekValue(int index) { 904ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (index < 0 || index >= mResourceData.length) { 905ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return null; 906ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 907ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 908ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski if (getValue(index, mValue)) { 909ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return mValue; 910ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 911ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 912ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return null; 913ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 914ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 915ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 916ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Returns a message about the parser state suitable for printing error messages. 917ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 918ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 919ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public String getPositionDescription() { 920ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return "<internal -- stub if needed>"; 921ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 922ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 923ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski /** 924ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Give back a previously retrieved TypedArray, for later re-use. 925ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */ 926ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 927ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public void recycle() { 928ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski // pass 929ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 930ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski 931ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski @Override 932ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski public String toString() { 933ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski return Arrays.toString(mResourceData); 934ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski } 935f0a7a1cb5b3ab8e9f46128c57dd8745e39706fbbDeepanshu Gupta 93632645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta /** 93732645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta * Searches for the string in the attributes (flag or enums) and returns the integer. 93832645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta * If found, it will return an integer matching the value. 93932645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta * 94032645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta * @param index Index of attribute to retrieve. 94132645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta * 94232645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta * @return Attribute int value, or null if not defined. 94332645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta */ 94432645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta private Integer resolveEnumAttribute(int index) { 94532645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta // Get the map of attribute-constant -> IntegerValue 94632645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta Map<String, Integer> map = null; 94732645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta if (mIsFramework[index]) { 94832645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta map = Bridge.getEnumValues(mNames[index]); 94932645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta } else { 95032645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta // get the styleable matching the resolved name 95132645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta RenderResources res = mContext.getRenderResources(); 95232645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta ResourceValue attr = res.getProjectResource(ResourceType.ATTR, mNames[index]); 95332645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta if (attr instanceof AttrResourceValue) { 95432645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta map = ((AttrResourceValue) attr).getAttributeValues(); 95532645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta } 95632645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta } 95732645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta 95832645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta if (map != null) { 95932645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta // accumulator to store the value of the 1+ constants. 96032645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta int result = 0; 96132645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta boolean found = false; 96232645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta 96332645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta // split the value in case this is a mix of several flags. 96432645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta String[] keywords = mResourceData[index].getValue().split("\\|"); 96532645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta for (String keyword : keywords) { 96632645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta Integer i = map.get(keyword.trim()); 96732645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta if (i != null) { 96832645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta result |= i; 96932645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta found = true; 97032645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta } 97132645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta // TODO: We should act smartly and log a warning for incorrect keywords. However, 97232645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta // this method is currently called even if the resourceValue is not an enum. 97332645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta } 97432645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta if (found) { 97532645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta return result; 97632645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta } 97732645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta } 97832645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta 97932645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta return null; 98032645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta } 98132645d9875e40b2b4719ce77a0c8bf753028e854Deepanshu Gupta 9821756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta /** 9831756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta * Copied from {@link XmlUtils#convertValueToInt(CharSequence, int)}, but adapted to account 9841756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta * for aapt, and the fact that host Java VM's Integer.parseInt("XXXXXXXX", 16) cannot handle 9851756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta * "XXXXXXXX" > 80000000. 9861756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta */ 9871756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta private static int convertValueToInt(@Nullable String charSeq, int defValue) { 988b7a03c66dfbfed6ce8197b1fbc2aec8925bc410cDeepanshu Gupta if (null == charSeq || charSeq.isEmpty()) 9891756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta return defValue; 9901756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta 9911756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta int sign = 1; 9921756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta int index = 0; 9931756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta int len = charSeq.length(); 9941756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta int base = 10; 9951756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta 9961756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta if ('-' == charSeq.charAt(0)) { 9971756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta sign = -1; 9981756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta index++; 9991756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } 10001756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta 10011756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta if ('0' == charSeq.charAt(index)) { 10021756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta // Quick check for a zero by itself 10031756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta if (index == (len - 1)) 10041756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta return 0; 10051756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta 10061756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta char c = charSeq.charAt(index + 1); 10071756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta 10081756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta if ('x' == c || 'X' == c) { 10091756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta index += 2; 10101756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta base = 16; 10111756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } else { 10121756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta index++; 10131756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta // Leave the base as 10. aapt removes the preceding zero, and thus when framework 10141756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta // sees the value, it only gets the decimal value. 10151756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } 10161756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } else if ('#' == charSeq.charAt(index)) { 10171756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta return ResourceHelper.getColor(charSeq) * sign; 10181756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } else if ("true".equals(charSeq) || "TRUE".equals(charSeq)) { 10191756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta return -1; 10201756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } else if ("false".equals(charSeq) || "FALSE".equals(charSeq)) { 10211756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta return 0; 10221756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } 10231756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta 10241756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta // Use Long, since we want to handle hex ints > 80000000. 10251756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta return ((int)Long.parseLong(charSeq.substring(index), base)) * sign; 10261756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta } 10271756dd0960657fca929ced5df044cd00e24b64dbDeepanshu Gupta 1028f0a7a1cb5b3ab8e9f46128c57dd8745e39706fbbDeepanshu Gupta static TypedArray obtain(Resources res, int len) { 1029896eb1c37f6a44d65d3a459891475e99170b657cDeepanshu Gupta return new BridgeTypedArray(res, null, len, true); 1030f0a7a1cb5b3ab8e9f46128c57dd8745e39706fbbDeepanshu Gupta } 1031f0a7a1cb5b3ab8e9f46128c57dd8745e39706fbbDeepanshu Gupta} 1032