1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Copyright (C) 2008 The Android Open Source Project 3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * you may not use this file except in compliance with the License. 6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * You may obtain a copy of the License at 7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Unless required by applicable law or agreed to in writing, software 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * See the License for the specific language governing permissions and 14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * limitations under the License. 15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipackage android.content.res; 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 196649ca371139831369e063b937e25d7d6e97b9e6Deepanshu Guptaimport com.android.ide.common.rendering.api.ArrayResourceValue; 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.AttrResourceValue; 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.LayoutLog; 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.RenderResources; 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.ResourceValue; 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.StyleResourceValue; 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.internal.util.XmlUtils; 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.Bridge; 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.android.BridgeContext; 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.impl.ResourceHelper; 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.resources.ResourceType; 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 31476e582d2ffdf25102d4c55f8c242baa3d21d37fDeepanshu Guptaimport android.annotation.Nullable; 326649ca371139831369e063b937e25d7d6e97b9e6Deepanshu Guptaimport android.content.res.Resources.NotFoundException; 334a605c6fa0027ee116beb29fbc9625721f0441f0Deepanshu Guptaimport android.content.res.Resources.Theme; 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.graphics.drawable.Drawable; 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.util.DisplayMetrics; 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.util.TypedValue; 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.view.LayoutInflater_Delegate; 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.view.ViewGroup.LayoutParams; 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 409ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Guptaimport java.util.ArrayList; 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.Arrays; 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.util.Map; 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 445779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Guptaimport static android.util.TypedValue.TYPE_ATTRIBUTE; 455779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Guptaimport static android.util.TypedValue.TYPE_DIMENSION; 465779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Guptaimport static android.util.TypedValue.TYPE_FLOAT; 475779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Guptaimport static android.util.TypedValue.TYPE_INT_BOOLEAN; 485779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Guptaimport static android.util.TypedValue.TYPE_INT_COLOR_ARGB4; 495779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Guptaimport static android.util.TypedValue.TYPE_INT_COLOR_ARGB8; 505779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Guptaimport static android.util.TypedValue.TYPE_INT_COLOR_RGB4; 515779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Guptaimport static android.util.TypedValue.TYPE_INT_COLOR_RGB8; 525779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Guptaimport static android.util.TypedValue.TYPE_INT_DEC; 535779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Guptaimport static android.util.TypedValue.TYPE_INT_HEX; 545779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Guptaimport static android.util.TypedValue.TYPE_NULL; 555779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Guptaimport static android.util.TypedValue.TYPE_REFERENCE; 565779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Guptaimport static android.util.TypedValue.TYPE_STRING; 575779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Guptaimport static com.android.SdkConstants.PREFIX_RESOURCE_REF; 585779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Guptaimport static com.android.SdkConstants.PREFIX_THEME_REF; 595779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Guptaimport static com.android.ide.common.rendering.api.RenderResources.REFERENCE_EMPTY; 605779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Guptaimport static com.android.ide.common.rendering.api.RenderResources.REFERENCE_NULL; 615779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Guptaimport static com.android.ide.common.rendering.api.RenderResources.REFERENCE_UNDEFINED; 629ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/** 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Custom implementation of TypedArray to handle non compiled resources. 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic final class BridgeTypedArray extends TypedArray { 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 68e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta private final Resources mBridgeResources; 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final BridgeContext mContext; 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski private final boolean mPlatformFile; 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 72831f3ce9b5b330101b090daf3163a843e0c6317eDeepanshu Gupta private final ResourceValue[] mResourceData; 73831f3ce9b5b330101b090daf3163a843e0c6317eDeepanshu Gupta private final String[] mNames; 74831f3ce9b5b330101b090daf3163a843e0c6317eDeepanshu Gupta private final boolean[] mIsFramework; 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 769ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta // Contains ids that are @empty. We still store null in mResourceData for that index, since we 779ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta // want to save on the check against empty, each time a resource value is requested. 789ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta @Nullable 799ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta private int[] mEmptyIds; 809ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta 81e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta public BridgeTypedArray(Resources resources, BridgeContext context, int len, 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski boolean platformFile) { 83857ba4af8519479298a671461cd6f5cace35b99bDeepanshu Gupta super(resources, null, null, 0); 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mBridgeResources = resources; 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mContext = context; 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mPlatformFile = platformFile; 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mResourceData = new ResourceValue[len]; 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mNames = new String[len]; 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mIsFramework = new boolean[len]; 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * A bridge-specific method that sets a value in the type array 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param index the index of the value in the TypedArray 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param name the name of the attribute 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param isFramework whether the attribute is in the android namespace. 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param value the value of the attribute 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void bridgeSetValue(int index, String name, boolean isFramework, ResourceValue value) { 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mResourceData[index] = value; 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mNames[index] = name; 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mIsFramework[index] = isFramework; 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 106831f3ce9b5b330101b090daf3163a843e0c6317eDeepanshu Gupta * Seals the array after all calls to 107831f3ce9b5b330101b090daf3163a843e0c6317eDeepanshu Gupta * {@link #bridgeSetValue(int, String, boolean, ResourceValue)} have been done. 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * <p/>This allows to compute the list of non default values, permitting 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * {@link #getIndexCount()} to return the proper value. 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void sealArray() { 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // fills TypedArray.mIndices which is used to implement getIndexCount/getIndexAt 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // first count the array size 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int count = 0; 1159ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta ArrayList<Integer> emptyIds = null; 116d4cf391c618e5f370f2cfd9f344baa895d5d3242Deepanshu Gupta for (int i = 0; i < mResourceData.length; i++) { 117d4cf391c618e5f370f2cfd9f344baa895d5d3242Deepanshu Gupta ResourceValue data = mResourceData[i]; 118d4cf391c618e5f370f2cfd9f344baa895d5d3242Deepanshu Gupta if (data != null) { 1199ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta String dataValue = data.getValue(); 1209ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta if (REFERENCE_NULL.equals(dataValue) || REFERENCE_UNDEFINED.equals(dataValue)) { 1219ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta mResourceData[i] = null; 1229ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta } else if (REFERENCE_EMPTY.equals(dataValue)) { 123d4cf391c618e5f370f2cfd9f344baa895d5d3242Deepanshu Gupta mResourceData[i] = null; 1249ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta if (emptyIds == null) { 1259ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta emptyIds = new ArrayList<Integer>(4); 1269ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta } 1279ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta emptyIds.add(i); 128d4cf391c618e5f370f2cfd9f344baa895d5d3242Deepanshu Gupta } else { 129d4cf391c618e5f370f2cfd9f344baa895d5d3242Deepanshu Gupta count++; 130d4cf391c618e5f370f2cfd9f344baa895d5d3242Deepanshu Gupta } 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1349ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta if (emptyIds != null) { 1359ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta mEmptyIds = new int[emptyIds.size()]; 1369ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta for (int i = 0; i < emptyIds.size(); i++) { 1379ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta mEmptyIds[i] = emptyIds.get(i); 1389ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta } 1399ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta } 1409ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // allocate the table with an extra to store the size 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mIndices = new int[count+1]; 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mIndices[0] = count; 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // fill the array with the indices. 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int index = 1; 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski for (int i = 0 ; i < mResourceData.length ; i++) { 148d4cf391c618e5f370f2cfd9f344baa895d5d3242Deepanshu Gupta if (mResourceData[i] != null) { 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mIndices[index++] = i; 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 1554a605c6fa0027ee116beb29fbc9625721f0441f0Deepanshu Gupta * Set the theme to be used for inflating drawables. 1564a605c6fa0027ee116beb29fbc9625721f0441f0Deepanshu Gupta */ 1574a605c6fa0027ee116beb29fbc9625721f0441f0Deepanshu Gupta public void setTheme(Theme theme) { 1584a605c6fa0027ee116beb29fbc9625721f0441f0Deepanshu Gupta mTheme = theme; 1594a605c6fa0027ee116beb29fbc9625721f0441f0Deepanshu Gupta } 1604a605c6fa0027ee116beb29fbc9625721f0441f0Deepanshu Gupta 1614a605c6fa0027ee116beb29fbc9625721f0441f0Deepanshu Gupta /** 162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Return the number of values in this array. 163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public int length() { 166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mResourceData.length; 167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Return the Resources object this array was loaded from. 171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public Resources getResources() { 174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mBridgeResources; 175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Retrieve the styled string value for the attribute at <var>index</var>. 179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param index Index of attribute to retrieve. 181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return CharSequence holding string data. May be styled. Returns 183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * null if the attribute is not defined. 184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public CharSequence getText(int index) { 187171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta // FIXME: handle styled strings! 188171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta return getString(index); 189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Retrieve the string value for the attribute at <var>index</var>. 193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param index Index of attribute to retrieve. 195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return String holding string data. Any styling information is 197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * removed. Returns null if the attribute is not defined. 198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public String getString(int index) { 201171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta if (!hasValue(index)) { 202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return null; 203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 204171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta // As unfortunate as it is, it's possible to use enums with all attribute formats, 2053c8140ab4b39922f92682910ce24de77fd512db4Deepanshu Gupta // not just integers/enums. So, we need to search the enums always. In case 206171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta // enums are used, the returned value is an integer. 207171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta Integer v = resolveEnumAttribute(index); 208171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta return v == null ? mResourceData[index].getValue() : String.valueOf((int) v); 209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Retrieve the boolean value for the attribute at <var>index</var>. 213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param index Index of attribute to retrieve. 215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param defValue Value to return if the attribute is not defined. 216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return Attribute boolean value, or defValue if not defined. 218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public boolean getBoolean(int index, boolean defValue) { 221171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta String s = getString(index); 222171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta return s == null ? defValue : XmlUtils.convertValueToBoolean(s, defValue); 223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Retrieve the integer value for the attribute at <var>index</var>. 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param index Index of attribute to retrieve. 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param defValue Value to return if the attribute is not defined. 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return Attribute int value, or defValue if not defined. 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public int getInt(int index, int defValue) { 236171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta String s = getString(index); 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski try { 2380437cac76c24dc6cac7b530e6d80f789565550ecDeepanshu Gupta return convertValueToInt(s, defValue); 239171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta } catch (NumberFormatException e) { 240171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, 2413c8140ab4b39922f92682910ce24de77fd512db4Deepanshu Gupta String.format("\"%1$s\" in attribute \"%2$s\" is not a valid integer", 242171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta s, mNames[index]), 243171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta null); 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Retrieve the float value for the attribute at <var>index</var>. 250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param index Index of attribute to retrieve. 252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return Attribute float value, or defValue if not defined.. 254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public float getFloat(int index, float defValue) { 257171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta String s = getString(index); 258171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta try { 259171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta if (s != null) { 260171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta return Float.parseFloat(s); 261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 262171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta } catch (NumberFormatException e) { 263171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, 2643c8140ab4b39922f92682910ce24de77fd512db4Deepanshu Gupta String.format("\"%1$s\" in attribute \"%2$s\" cannot be converted to float.", 265171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta s, mNames[index]), 266171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta null); 267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Retrieve the color value for the attribute at <var>index</var>. If 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * the attribute references a color resource holding a complex 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * {@link android.content.res.ColorStateList}, then the default color from 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * the set is returned. 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param index Index of attribute to retrieve. 278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param defValue Value to return if the attribute is not defined or 279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * not a resource. 280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return Attribute color value, or defValue if not defined. 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public int getColor(int index, int defValue) { 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index < 0 || index >= mResourceData.length) { 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mResourceData[index] == null) { 290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ColorStateList colorStateList = ResourceHelper.getColorStateList( 294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mResourceData[index], mContext); 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (colorStateList != null) { 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return colorStateList.getDefaultColor(); 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 3025d1013cf13e59b7f8dc8f16b5811cb29982e0ef3Diego Perez @Override 303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public ColorStateList getColorStateList(int index) { 304171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta if (!hasValue(index)) { 305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return null; 306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 308566b303365078fac9a454f1595add19e02631db3Diego Perez return ResourceHelper.getColorStateList(mResourceData[index], mContext); 309566b303365078fac9a454f1595add19e02631db3Diego Perez } 310b63da06a7ab9ad06184b0359abddd9137742ea4aJerome Gaillard 311566b303365078fac9a454f1595add19e02631db3Diego Perez @Override 312566b303365078fac9a454f1595add19e02631db3Diego Perez public ComplexColor getComplexColor(int index) { 313566b303365078fac9a454f1595add19e02631db3Diego Perez if (!hasValue(index)) { 314b63da06a7ab9ad06184b0359abddd9137742ea4aJerome Gaillard return null; 315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 317566b303365078fac9a454f1595add19e02631db3Diego Perez return ResourceHelper.getComplexColor(mResourceData[index], mContext); 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Retrieve the integer value for the attribute at <var>index</var>. 322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param index Index of attribute to retrieve. 324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param defValue Value to return if the attribute is not defined or 325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * not a resource. 326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return Attribute integer value, or defValue if not defined. 328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public int getInteger(int index, int defValue) { 331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return getInt(index, defValue); 332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Retrieve a dimensional unit attribute at <var>index</var>. Unit 336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * conversions are based on the current {@link DisplayMetrics} 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * associated with the resources this {@link TypedArray} object 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * came from. 339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param index Index of attribute to retrieve. 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param defValue Value to return if the attribute is not defined or 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * not a resource. 343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return Attribute dimension value multiplied by the appropriate 345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * metric, or defValue if not defined. 346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see #getDimensionPixelOffset 348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see #getDimensionPixelSize 349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public float getDimension(int index, float defValue) { 352171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta String s = getString(index); 353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (s == null) { 354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 356171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta // Check if the value is a magic constant that doesn't require a unit. 357171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta try { 358171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta int i = Integer.parseInt(s); 359171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta if (i == LayoutParams.MATCH_PARENT || i == LayoutParams.WRAP_CONTENT) { 360171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta return i; 361171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta } 362171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta } catch (NumberFormatException ignored) { 363171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta // pass 364171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta } 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 366d4cf391c618e5f370f2cfd9f344baa895d5d3242Deepanshu Gupta if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) { 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mValue.getDimension(mBridgeResources.getDisplayMetrics()); 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 370171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta return defValue; 371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Retrieve a dimensional unit attribute at <var>index</var> for use 375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * as an offset in raw pixels. This is the same as 376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * {@link #getDimension}, except the returned value is converted to 377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * integer pixels for you. An offset conversion involves simply 378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * truncating the base value to an integer. 379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param index Index of attribute to retrieve. 381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param defValue Value to return if the attribute is not defined or 382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * not a resource. 383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return Attribute dimension value multiplied by the appropriate 385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * metric and truncated to integer pixels, or defValue if not defined. 386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see #getDimension 388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see #getDimensionPixelSize 389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public int getDimensionPixelOffset(int index, int defValue) { 392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return (int) getDimension(index, defValue); 393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Retrieve a dimensional unit attribute at <var>index</var> for use 397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * as a size in raw pixels. This is the same as 398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * {@link #getDimension}, except the returned value is converted to 399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * integer pixels for use as a size. A size conversion involves 400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * rounding the base value, and ensuring that a non-zero base value 401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * is at least one pixel in size. 402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param index Index of attribute to retrieve. 404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param defValue Value to return if the attribute is not defined or 405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * not a resource. 406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return Attribute dimension value multiplied by the appropriate 408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * metric and truncated to integer pixels, or defValue if not defined. 409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see #getDimension 411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @see #getDimensionPixelOffset 412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public int getDimensionPixelSize(int index, int defValue) { 415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski try { 41621b564573327b1ed2f7e06146b8a01c47ede3089Deepanshu Gupta return getDimension(index, null); 417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } catch (RuntimeException e) { 418171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta String s = getString(index); 419171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta 420171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta if (s != null) { 421171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta // looks like we were unable to resolve the dimension value 422171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, 423171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta String.format("\"%1$s\" in attribute \"%2$s\" is not a valid format.", 424d4cf391c618e5f370f2cfd9f344baa895d5d3242Deepanshu Gupta s, mNames[index]), null); 425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Special version of {@link #getDimensionPixelSize} for retrieving 433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * {@link android.view.ViewGroup}'s layout_width and layout_height 434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * attributes. This is only here for performance reasons; applications 435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * should use {@link #getDimensionPixelSize}. 436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param index Index of the attribute to retrieve. 438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param name Textual name of attribute for error reporting. 439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return Attribute dimension value multiplied by the appropriate 441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * metric and truncated to integer pixels. 442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public int getLayoutDimension(int index, String name) { 445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski try { 44621b564573327b1ed2f7e06146b8a01c47ede3089Deepanshu Gupta // this will throw an exception if not found. 44721b564573327b1ed2f7e06146b8a01c47ede3089Deepanshu Gupta return getDimension(index, name); 448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } catch (RuntimeException e) { 449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (LayoutInflater_Delegate.sIsInInclude) { 45121b564573327b1ed2f7e06146b8a01c47ede3089Deepanshu Gupta throw new RuntimeException("Layout Dimension '" + name + "' not found."); 452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, 455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "You must supply a " + name + " attribute.", null); 456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return 0; 458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public int getLayoutDimension(int index, int defValue) { 463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return getDimensionPixelSize(index, defValue); 464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 46621b564573327b1ed2f7e06146b8a01c47ede3089Deepanshu Gupta /** @param name attribute name, used for error reporting. */ 46721b564573327b1ed2f7e06146b8a01c47ede3089Deepanshu Gupta private int getDimension(int index, @Nullable String name) { 468171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta String s = getString(index); 469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (s == null) { 47021b564573327b1ed2f7e06146b8a01c47ede3089Deepanshu Gupta if (name != null) { 47121b564573327b1ed2f7e06146b8a01c47ede3089Deepanshu Gupta throw new RuntimeException("Attribute '" + name + "' not found"); 47221b564573327b1ed2f7e06146b8a01c47ede3089Deepanshu Gupta } 473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski throw new RuntimeException(); 474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 475171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta // Check if the value is a magic constant that doesn't require a unit. 476171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta try { 477171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta int i = Integer.parseInt(s); 478171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta if (i == LayoutParams.MATCH_PARENT || i == LayoutParams.WRAP_CONTENT) { 479171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta return i; 480171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta } 481171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta } catch (NumberFormatException ignored) { 482171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta // pass 483171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta } 484d4cf391c618e5f370f2cfd9f344baa895d5d3242Deepanshu Gupta if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) { 485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski float f = mValue.getDimension(mBridgeResources.getDisplayMetrics()); 486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski final int res = (int)(f+0.5f); 488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (res != 0) return res; 489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (f == 0) return 0; 490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (f > 0) return 1; 491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski throw new RuntimeException(); 494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Retrieve a fractional unit attribute at <var>index</var>. 498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param index Index of attribute to retrieve. 500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param base The base value of this fraction. In other words, a 501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * standard fraction is multiplied by this value. 502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param pbase The parent base value of this fraction. In other 503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * words, a parent fraction (nn%p) is multiplied by this 504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * value. 505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param defValue Value to return if the attribute is not defined or 506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * not a resource. 507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return Attribute fractional value multiplied by the appropriate 509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * base value, or defValue if not defined. 510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public float getFraction(int index, int base, int pbase, float defValue) { 513171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta String value = getString(index); 514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value == null) { 515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 518d4cf391c618e5f370f2cfd9f344baa895d5d3242Deepanshu Gupta if (ResourceHelper.parseFloatAttribute(mNames[index], value, mValue, false)) { 519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mValue.getFraction(base, pbase); 520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // looks like we were unable to resolve the fraction value 523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT, 524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String.format( 525d4cf391c618e5f370f2cfd9f344baa895d5d3242Deepanshu Gupta "\"%1$s\" in attribute \"%2$s\" cannot be converted to a fraction.", 526d4cf391c618e5f370f2cfd9f344baa895d5d3242Deepanshu Gupta value, mNames[index]), null); 527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Retrieve the resource identifier for the attribute at 533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * <var>index</var>. Note that attribute resource as resolved when 534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * the overall {@link TypedArray} object is retrieved. As a 535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * result, this function will return the resource identifier of the 536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * final resource value that was found, <em>not</em> necessarily the 537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * original resource that was specified by the attribute. 538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param index Index of attribute to retrieve. 540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param defValue Value to return if the attribute is not defined or 541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * not a resource. 542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return Attribute resource identifier, or defValue if not defined. 544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public int getResourceId(int index, int defValue) { 547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index < 0 || index >= mResourceData.length) { 548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // get the Resource for this index 552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceValue resValue = mResourceData[index]; 553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // no data, return the default value. 555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (resValue == null) { 556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // check if this is a style resource 560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (resValue instanceof StyleResourceValue) { 561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // get the id that will represent this style. 562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mContext.getDynamicIdByStyle((StyleResourceValue)resValue); 563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if the attribute was a reference to a resource, and not a declaration of an id (@+id), 566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // then the xml attribute value was "resolved" which leads us to a ResourceValue with a 567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // valid getType() and getName() returning a resource name. 568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // (and getValue() returning null!). We need to handle this! 569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (resValue.getResourceType() != null) { 570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if this is a framework id 571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mPlatformFile || resValue.isFramework()) { 572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // look for idName in the android R classes 573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mContext.getFrameworkResourceValue( 574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resValue.getResourceType(), resValue.getName(), defValue); 575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // look for idName in the project R class. 578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mContext.getProjectResourceValue( 579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resValue.getResourceType(), resValue.getName(), defValue); 580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // else, try to get the value, and resolve it somehow. 583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String value = resValue.getValue(); 584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value == null) { 585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if the value is just an integer, return it. 589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski try { 590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int i = Integer.parseInt(value); 591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (Integer.toString(i).equals(value)) { 592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return i; 593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } catch (NumberFormatException e) { 595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Handle the @id/<name>, @+id/<name> and @android:id/<name> 599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // We need to return the exact value that was compiled (from the various R classes), 600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // as these values can be reused internally with calls to findViewById(). 601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // There's a trick with platform layouts that not use "android:" but their IDs are in 602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // fact in the android.R and com.android.internal.R classes. 603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // The field mPlatformFile will indicate that all IDs are to be looked up in the android R 604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // classes exclusively. 605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if this is a reference to an id, find it. 607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (value.startsWith("@id/") || value.startsWith("@+") || 608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski value.startsWith("@android:id/")) { 609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int pos = value.indexOf('/'); 611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String idName = value.substring(pos + 1); 612b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta boolean create = value.startsWith("@+"); 613b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta boolean isFrameworkId = 614b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta mPlatformFile || value.startsWith("@android") || value.startsWith("@+android"); 615b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta 616b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta // Look for the idName in project or android R class depending on isPlatform. 617b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta if (create) { 618b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta Integer idValue; 619b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta if (isFrameworkId) { 620b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta idValue = Bridge.getResourceId(ResourceType.ID, idName); 621b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta } else { 62237dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta idValue = mContext.getLayoutlibCallback().getResourceId(ResourceType.ID, idName); 623b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta } 624b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta return idValue == null ? defValue : idValue; 625b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta } 626b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta // This calls the same method as in if(create), but doesn't create a dynamic id, if 627b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta // one is not found. 628b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta if (isFrameworkId) { 629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mContext.getFrameworkResourceValue(ResourceType.ID, idName, defValue); 630b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta } else { 631b6864ac6cde109be320e18188209eb8420c585f1Deepanshu Gupta return mContext.getProjectResourceValue(ResourceType.ID, idName, defValue); 632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // not a direct id valid reference? resolve it 636831f3ce9b5b330101b090daf3163a843e0c6317eDeepanshu Gupta Integer idValue; 637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (resValue.isFramework()) { 639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski idValue = Bridge.getResourceId(resValue.getResourceType(), 640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resValue.getName()); 641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 64237dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta idValue = mContext.getLayoutlibCallback().getResourceId( 643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resValue.getResourceType(), resValue.getName()); 644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (idValue != null) { 647831f3ce9b5b330101b090daf3163a843e0c6317eDeepanshu Gupta return idValue; 648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_RESOLVE, 651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski String.format( 652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "Unable to resolve id \"%1$s\" for attribute \"%2$s\"", value, mNames[index]), 653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski resValue); 654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return defValue; 656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 658831f3ce9b5b330101b090daf3163a843e0c6317eDeepanshu Gupta @Override 659831f3ce9b5b330101b090daf3163a843e0c6317eDeepanshu Gupta public int getThemeAttributeId(int index, int defValue) { 660831f3ce9b5b330101b090daf3163a843e0c6317eDeepanshu Gupta // TODO: Get the right Theme Attribute ID to enable caching of the drawables. 661831f3ce9b5b330101b090daf3163a843e0c6317eDeepanshu Gupta return defValue; 662831f3ce9b5b330101b090daf3163a843e0c6317eDeepanshu Gupta } 663831f3ce9b5b330101b090daf3163a843e0c6317eDeepanshu Gupta 664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Retrieve the Drawable for the attribute at <var>index</var>. This 666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * gets the resource ID of the selected attribute, and uses 667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * {@link Resources#getDrawable Resources.getDrawable} of the owning 668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Resources object to retrieve its Drawable. 669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param index Index of attribute to retrieve. 671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return Drawable for the attribute, or null if not defined. 673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public Drawable getDrawable(int index) { 676171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta if (!hasValue(index)) { 677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return null; 678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ResourceValue value = mResourceData[index]; 6814a605c6fa0027ee116beb29fbc9625721f0441f0Deepanshu Gupta return ResourceHelper.getDrawable(value, mContext, mTheme); 682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Retrieve the CharSequence[] for the attribute at <var>index</var>. 687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * This gets the resource ID of the selected attribute, and uses 688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * {@link Resources#getTextArray Resources.getTextArray} of the owning 689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Resources object to retrieve its String[]. 690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param index Index of attribute to retrieve. 692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return CharSequence[] for the attribute, or null if not defined. 694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public CharSequence[] getTextArray(int index) { 6976649ca371139831369e063b937e25d7d6e97b9e6Deepanshu Gupta if (!hasValue(index)) { 6986649ca371139831369e063b937e25d7d6e97b9e6Deepanshu Gupta return null; 699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 7006649ca371139831369e063b937e25d7d6e97b9e6Deepanshu Gupta ResourceValue resVal = mResourceData[index]; 7016649ca371139831369e063b937e25d7d6e97b9e6Deepanshu Gupta if (resVal instanceof ArrayResourceValue) { 7026649ca371139831369e063b937e25d7d6e97b9e6Deepanshu Gupta ArrayResourceValue array = (ArrayResourceValue) resVal; 7036649ca371139831369e063b937e25d7d6e97b9e6Deepanshu Gupta int count = array.getElementCount(); 704e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta return count >= 0 ? Resources_Delegate.fillValues(mBridgeResources, array, new CharSequence[count]) : 705e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta null; 7066649ca371139831369e063b937e25d7d6e97b9e6Deepanshu Gupta } 7076649ca371139831369e063b937e25d7d6e97b9e6Deepanshu Gupta int id = getResourceId(index, 0); 7086649ca371139831369e063b937e25d7d6e97b9e6Deepanshu Gupta String resIdMessage = id > 0 ? " (resource id 0x" + Integer.toHexString(id) + ')' : ""; 7096649ca371139831369e063b937e25d7d6e97b9e6Deepanshu Gupta throw new NotFoundException( 7106649ca371139831369e063b937e25d7d6e97b9e6Deepanshu Gupta String.format("%1$s in %2$s%3$s is not a valid array resource.", 7116649ca371139831369e063b937e25d7d6e97b9e6Deepanshu Gupta resVal.getValue(), mNames[index], resIdMessage)); 712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 714dc62340f18becf51f6f3c94d3994665bcd7dd537Deepanshu Gupta @Override 715dc62340f18becf51f6f3c94d3994665bcd7dd537Deepanshu Gupta public int[] extractThemeAttrs() { 71626e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta // The drawables are always inflated with a Theme and we don't care about caching. So, 71726e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta // just return. 718dc62340f18becf51f6f3c94d3994665bcd7dd537Deepanshu Gupta return null; 719dc62340f18becf51f6f3c94d3994665bcd7dd537Deepanshu Gupta } 720dc62340f18becf51f6f3c94d3994665bcd7dd537Deepanshu Gupta 72126e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta @Override 72226e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta public int getChangingConfigurations() { 72326e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta // We don't care about caching. Any change in configuration is a fresh render. So, 72426e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta // just return. 72526e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta return 0; 72626e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta } 72726e32ea559da98dcdebaefb74d4f3c1a5ce705c3Deepanshu Gupta 728282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Retrieve the raw TypedValue for the attribute at <var>index</var>. 730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param index Index of attribute to retrieve. 732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param outValue TypedValue object in which to place the attribute's 733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * data. 734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 735282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return Returns true if the value was retrieved, else false. 736282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 737282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 738282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public boolean getValue(int index, TypedValue outValue) { 739171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta String s = getString(index); 740171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta return s != null && ResourceHelper.parseFloatAttribute(mNames[index], s, outValue, false); 741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 743d77b9ed7dcc42efca33b225c4594a30aab9e709cDeepanshu Gupta @Override 7445779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta @SuppressWarnings("ResultOfMethodCallIgnored") 745d77b9ed7dcc42efca33b225c4594a30aab9e709cDeepanshu Gupta public int getType(int index) { 7465779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta String value = getString(index); 7475779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta if (value == null) { 7485779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta return TYPE_NULL; 749d77b9ed7dcc42efca33b225c4594a30aab9e709cDeepanshu Gupta } 7505779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta if (value.startsWith(PREFIX_RESOURCE_REF)) { 7515779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta return TYPE_REFERENCE; 7525779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } 7535779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta if (value.startsWith(PREFIX_THEME_REF)) { 7545779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta return TYPE_ATTRIBUTE; 7555779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } 7565779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta try { 7575779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta // Don't care about the value. Only called to check if an exception is thrown. 7585779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta convertValueToInt(value, 0); 7595779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta if (value.startsWith("0x") || value.startsWith("0X")) { 7605779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta return TYPE_INT_HEX; 7615779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } 7625779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta // is it a color? 7635779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta if (value.startsWith("#")) { 7645779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta int length = value.length() - 1; 7655779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta if (length == 3) { // rgb 7665779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta return TYPE_INT_COLOR_RGB4; 7675779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } 7685779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta if (length == 4) { // argb 7695779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta return TYPE_INT_COLOR_ARGB4; 7705779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } 7715779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta if (length == 6) { // rrggbb 7725779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta return TYPE_INT_COLOR_RGB8; 7735779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } 7745779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta if (length == 8) { // aarrggbb 7755779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta return TYPE_INT_COLOR_ARGB8; 7765779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } 7775779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } 7785779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) { 7795779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta return TYPE_INT_BOOLEAN; 7805779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } 7815779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta return TYPE_INT_DEC; 7825779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } catch (NumberFormatException ignored) { 7835779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta try { 7845779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta Float.parseFloat(value); 7855779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta return TYPE_FLOAT; 7865779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } catch (NumberFormatException ignore) { 7875779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } 7885779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta // Might be a dimension. 7895779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta if (ResourceHelper.parseFloatAttribute(null, value, new TypedValue(), false)) { 7905779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta return TYPE_DIMENSION; 7915779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } 7925779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } 7935779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta // TODO: handle fractions. 7945779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta return TYPE_STRING; 795d77b9ed7dcc42efca33b225c4594a30aab9e709cDeepanshu Gupta } 796d77b9ed7dcc42efca33b225c4594a30aab9e709cDeepanshu Gupta 797282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 798282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Determines whether there is an attribute at <var>index</var>. 799282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 800282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param index Index of attribute to retrieve. 801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return True if the attribute has a value, false otherwise. 803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 805282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public boolean hasValue(int index) { 806171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta return index >= 0 && index < mResourceData.length && mResourceData[index] != null; 807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 8099ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta @Override 8109ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta public boolean hasValueOrEmpty(int index) { 8119ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta return hasValue(index) || index >= 0 && index < mResourceData.length && 8129ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta mEmptyIds != null && Arrays.binarySearch(mEmptyIds, index) >= 0; 8139ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta } 8149ca97747260b9906fc3a159ce3930109022cf2ddDeepanshu Gupta 815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Retrieve the raw TypedValue for the attribute at <var>index</var> 817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * and return a temporary object holding its data. This object is only 818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * valid until the next call on to {@link TypedArray}. 819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @param index Index of attribute to retrieve. 821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * @return Returns a TypedValue object if the attribute is defined, 823282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * containing its data; otherwise returns null. (You will not 824282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * receive a TypedValue whose type is TYPE_NULL.) 825282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public TypedValue peekValue(int index) { 828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (index < 0 || index >= mResourceData.length) { 829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return null; 830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (getValue(index, mValue)) { 833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mValue; 834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return null; 837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns a message about the parser state suitable for printing error messages. 841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public String getPositionDescription() { 844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return "<internal -- stub if needed>"; 845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /** 848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Give back a previously retrieved TypedArray, for later re-use. 849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public void recycle() { 852282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // pass 853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski @Override 856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski public String toString() { 857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return Arrays.toString(mResourceData); 858282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 859dc62340f18becf51f6f3c94d3994665bcd7dd537Deepanshu Gupta 860171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta /** 861171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta * Searches for the string in the attributes (flag or enums) and returns the integer. 862171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta * If found, it will return an integer matching the value. 863171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta * 864171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta * @param index Index of attribute to retrieve. 865171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta * 866171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta * @return Attribute int value, or null if not defined. 867171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta */ 868171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta private Integer resolveEnumAttribute(int index) { 869171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta // Get the map of attribute-constant -> IntegerValue 870171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta Map<String, Integer> map = null; 871171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta if (mIsFramework[index]) { 872171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta map = Bridge.getEnumValues(mNames[index]); 873171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta } else { 874171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta // get the styleable matching the resolved name 875171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta RenderResources res = mContext.getRenderResources(); 876171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta ResourceValue attr = res.getProjectResource(ResourceType.ATTR, mNames[index]); 877171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta if (attr instanceof AttrResourceValue) { 878171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta map = ((AttrResourceValue) attr).getAttributeValues(); 879171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta } 880171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta } 881171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta 882171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta if (map != null) { 883171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta // accumulator to store the value of the 1+ constants. 884171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta int result = 0; 885171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta boolean found = false; 886171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta 887171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta // split the value in case this is a mix of several flags. 888171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta String[] keywords = mResourceData[index].getValue().split("\\|"); 889171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta for (String keyword : keywords) { 890171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta Integer i = map.get(keyword.trim()); 891171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta if (i != null) { 892171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta result |= i; 893171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta found = true; 894171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta } 895171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta // TODO: We should act smartly and log a warning for incorrect keywords. However, 896171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta // this method is currently called even if the resourceValue is not an enum. 897171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta } 898171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta if (found) { 899171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta return result; 900171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta } 901171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta } 902171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta 903171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta return null; 904171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta } 905171804201dd556f8ce7ee7618661a5c8ee71507aDeepanshu Gupta 9065779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta /** 9075779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta * Copied from {@link XmlUtils#convertValueToInt(CharSequence, int)}, but adapted to account 9085779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta * for aapt, and the fact that host Java VM's Integer.parseInt("XXXXXXXX", 16) cannot handle 9095779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta * "XXXXXXXX" > 80000000. 9105779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta */ 9115779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta private static int convertValueToInt(@Nullable String charSeq, int defValue) { 9120437cac76c24dc6cac7b530e6d80f789565550ecDeepanshu Gupta if (null == charSeq || charSeq.isEmpty()) 9135779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta return defValue; 9145779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta 9155779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta int sign = 1; 9165779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta int index = 0; 9175779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta int len = charSeq.length(); 9185779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta int base = 10; 9195779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta 9205779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta if ('-' == charSeq.charAt(0)) { 9215779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta sign = -1; 9225779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta index++; 9235779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } 9245779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta 9255779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta if ('0' == charSeq.charAt(index)) { 9265779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta // Quick check for a zero by itself 9275779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta if (index == (len - 1)) 9285779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta return 0; 9295779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta 9305779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta char c = charSeq.charAt(index + 1); 9315779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta 9325779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta if ('x' == c || 'X' == c) { 9335779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta index += 2; 9345779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta base = 16; 9355779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } else { 9365779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta index++; 9375779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta // Leave the base as 10. aapt removes the preceding zero, and thus when framework 9385779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta // sees the value, it only gets the decimal value. 9395779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } 9405779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } else if ('#' == charSeq.charAt(index)) { 9415779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta return ResourceHelper.getColor(charSeq) * sign; 9425779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } else if ("true".equals(charSeq) || "TRUE".equals(charSeq)) { 9435779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta return -1; 9445779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } else if ("false".equals(charSeq) || "FALSE".equals(charSeq)) { 9455779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta return 0; 9465779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } 9475779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta 9485779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta // Use Long, since we want to handle hex ints > 80000000. 9495779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta return ((int)Long.parseLong(charSeq.substring(index), base)) * sign; 9505779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta } 9515779ad71eabed3aabaefef1e4749693f8320816eDeepanshu Gupta 952dc62340f18becf51f6f3c94d3994665bcd7dd537Deepanshu Gupta static TypedArray obtain(Resources res, int len) { 953e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta return new BridgeTypedArray(res, null, len, true); 954dc62340f18becf51f6f3c94d3994665bcd7dd537Deepanshu Gupta } 955dc62340f18becf51f6f3c94d3994665bcd7dd537Deepanshu Gupta} 956