1a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki/* 2a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * Copyright (C) 2015 The Android Open Source Project 3a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * 4a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * Licensed under the Apache License, Version 2.0 (the "License"); 5a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * you may not use this file except in compliance with the License. 6a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * You may obtain a copy of the License at 7a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * 8a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * http://www.apache.org/licenses/LICENSE-2.0 9a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * 10a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * Unless required by applicable law or agreed to in writing, software 11a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * distributed under the License is distributed on an "AS IS" BASIS, 12a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * See the License for the specific language governing permissions and 14a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * limitations under the License. 15a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki */ 16a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Arakipackage android.support.v4.content.res; 17a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki 18a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Arakiimport static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP; 19a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki 20a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Arakiimport android.content.Context; 21b6086751979cb14740815502597e9fcfddb7054aztenghuiimport android.content.res.Resources; 22a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Arakiimport android.content.res.TypedArray; 23a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Arakiimport android.graphics.drawable.Drawable; 24a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Arakiimport android.support.annotation.AnyRes; 25a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Arakiimport android.support.annotation.ColorInt; 26a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Arakiimport android.support.annotation.NonNull; 27a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Arakiimport android.support.annotation.RestrictTo; 28a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Arakiimport android.support.annotation.StyleableRes; 29b6086751979cb14740815502597e9fcfddb7054aztenghuiimport android.util.AttributeSet; 30a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Arakiimport android.util.TypedValue; 31a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki 32a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Arakiimport org.xmlpull.v1.XmlPullParser; 33a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki 34a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki/** 35a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * Compat methods for accessing TypedArray values. 36a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * 37b6086751979cb14740815502597e9fcfddb7054aztenghui * All the getNamed*() functions added the attribute name match, to take care of potential ID 38b6086751979cb14740815502597e9fcfddb7054aztenghui * collision between the private attributes in older OS version (OEM) and the attributes existed in 39b6086751979cb14740815502597e9fcfddb7054aztenghui * the newer OS version. 40b6086751979cb14740815502597e9fcfddb7054aztenghui * For example, if an private attribute named "abcdefg" in Kitkat has the 41b6086751979cb14740815502597e9fcfddb7054aztenghui * same id value as "android:pathData" in Lollipop, we need to match the attribute's namefirst. 42b6086751979cb14740815502597e9fcfddb7054aztenghui * 43a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * @hide 44a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki */ 45a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki@RestrictTo(LIBRARY_GROUP) 46a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Arakipublic class TypedArrayUtils { 47a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki 48a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki private static final String NAMESPACE = "http://schemas.android.com/apk/res/android"; 49a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki 50a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki /** 51a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * @return Whether the current node ofthe {@link XmlPullParser} has an attribute with the 52a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * specified {@code attrName}. 53a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki */ 54a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki public static boolean hasAttribute(@NonNull XmlPullParser parser, @NonNull String attrName) { 55a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki return parser.getAttributeValue(NAMESPACE, attrName) != null; 56a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 57a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki 58a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki /** 59a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * Retrieves a float attribute value. In addition to the styleable resource ID, we also make 60a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * sure that the attribute name matches. 61a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * 62a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * @return a float value in the {@link TypedArray} with the specified {@code resId}, or 63a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * {@code defaultValue} if it does not exist. 64a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki */ 65a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki public static float getNamedFloat(@NonNull TypedArray a, @NonNull XmlPullParser parser, 66a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki @NonNull String attrName, @StyleableRes int resId, float defaultValue) { 67a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki final boolean hasAttr = hasAttribute(parser, attrName); 68a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki if (!hasAttr) { 69a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki return defaultValue; 70a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } else { 71a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki return a.getFloat(resId, defaultValue); 72a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 73a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 74a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki 75a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki /** 76a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * Retrieves a boolean attribute value. In addition to the styleable resource ID, we also make 77a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * sure that the attribute name matches. 78a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * 79a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * @return a boolean value in the {@link TypedArray} with the specified {@code resId}, or 80a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * {@code defaultValue} if it does not exist. 81a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki */ 82a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki public static boolean getNamedBoolean(@NonNull TypedArray a, @NonNull XmlPullParser parser, 83a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki String attrName, @StyleableRes int resId, boolean defaultValue) { 84a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki final boolean hasAttr = hasAttribute(parser, attrName); 85a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki if (!hasAttr) { 86a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki return defaultValue; 87a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } else { 88a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki return a.getBoolean(resId, defaultValue); 89a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 90a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 91a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki 92a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki /** 93a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * Retrieves an int attribute value. In addition to the styleable resource ID, we also make 94a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * sure that the attribute name matches. 95a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * 96a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * @return an int value in the {@link TypedArray} with the specified {@code resId}, or 97a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * {@code defaultValue} if it does not exist. 98a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki */ 998158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki public static int getNamedInt(@NonNull TypedArray a, @NonNull XmlPullParser parser, 1008158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki String attrName, @StyleableRes int resId, int defaultValue) { 101a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki final boolean hasAttr = hasAttribute(parser, attrName); 102a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki if (!hasAttr) { 103a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki return defaultValue; 104a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } else { 105a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki return a.getInt(resId, defaultValue); 106a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 107a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 108a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki 109a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki /** 110a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * Retrieves a color attribute value. In addition to the styleable resource ID, we also make 111a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * sure that the attribute name matches. 112a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * 113a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * @return a color value in the {@link TypedArray} with the specified {@code resId}, or 114a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * {@code defaultValue} if it does not exist. 115a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki */ 116a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki @ColorInt 117a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki public static int getNamedColor(@NonNull TypedArray a, @NonNull XmlPullParser parser, 118a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki String attrName, @StyleableRes int resId, @ColorInt int defaultValue) { 119a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki final boolean hasAttr = hasAttribute(parser, attrName); 120a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki if (!hasAttr) { 121a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki return defaultValue; 122a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } else { 123a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki return a.getColor(resId, defaultValue); 124a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 125a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 126a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki 127a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki /** 1288158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki * Retrieves a resource ID attribute value. In addition to the styleable resource ID, we also 1298158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki * make sure that the attribute name matches. 1308158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki * 1318158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki * @return a resource ID value in the {@link TypedArray} with the specified {@code resId}, or 1328158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki * {@code defaultValue} if it does not exist. 1338158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki */ 1348158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki @AnyRes 1358158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki public static int getNamedResourceId(@NonNull TypedArray a, @NonNull XmlPullParser parser, 1368158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki String attrName, @StyleableRes int resId, @AnyRes int defaultValue) { 1378158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki final boolean hasAttr = hasAttribute(parser, attrName); 1388158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki if (!hasAttr) { 1398158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki return defaultValue; 1408158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki } else { 1418158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki return a.getResourceId(resId, defaultValue); 1428158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki } 1438158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki } 1448158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki 1458158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki /** 1468158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki * Retrieves a string attribute value. In addition to the styleable resource ID, we also 1478158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki * make sure that the attribute name matches. 1488158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki * 1498158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki * @return a string value in the {@link TypedArray} with the specified {@code resId}, or 1508158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki * null if it does not exist. 1518158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki */ 1528158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki public static String getNamedString(@NonNull TypedArray a, @NonNull XmlPullParser parser, 1538158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki String attrName, @StyleableRes int resId) { 1548158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki final boolean hasAttr = hasAttribute(parser, attrName); 1558158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki if (!hasAttr) { 1568158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki return null; 1578158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki } else { 1588158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki return a.getString(resId); 1598158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki } 1608158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki } 1618158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki 1628158051cdfef95fc1f22b56bba93b9c610f5ecb1Yuichi Araki /** 163b6086751979cb14740815502597e9fcfddb7054aztenghui * Retrieve the raw TypedValue for the attribute at <var>index</var> 164b6086751979cb14740815502597e9fcfddb7054aztenghui * and return a temporary object holding its data. This object is only 165b6086751979cb14740815502597e9fcfddb7054aztenghui * valid until the next call on to {@link TypedArray}. 166b6086751979cb14740815502597e9fcfddb7054aztenghui */ 167b6086751979cb14740815502597e9fcfddb7054aztenghui public static TypedValue peekNamedValue(TypedArray a, XmlPullParser parser, String attrName, 168b6086751979cb14740815502597e9fcfddb7054aztenghui int resId) { 169b6086751979cb14740815502597e9fcfddb7054aztenghui final boolean hasAttr = hasAttribute(parser, attrName); 170b6086751979cb14740815502597e9fcfddb7054aztenghui if (!hasAttr) { 171b6086751979cb14740815502597e9fcfddb7054aztenghui return null; 172b6086751979cb14740815502597e9fcfddb7054aztenghui } else { 173b6086751979cb14740815502597e9fcfddb7054aztenghui return a.peekValue(resId); 174b6086751979cb14740815502597e9fcfddb7054aztenghui } 175b6086751979cb14740815502597e9fcfddb7054aztenghui } 176b6086751979cb14740815502597e9fcfddb7054aztenghui 177b6086751979cb14740815502597e9fcfddb7054aztenghui /** 178b6086751979cb14740815502597e9fcfddb7054aztenghui * Obtains styled attributes from the theme, if available, or unstyled 179b6086751979cb14740815502597e9fcfddb7054aztenghui * resources if the theme is null. 180b6086751979cb14740815502597e9fcfddb7054aztenghui */ 181b6086751979cb14740815502597e9fcfddb7054aztenghui public static TypedArray obtainAttributes( 182b6086751979cb14740815502597e9fcfddb7054aztenghui Resources res, Resources.Theme theme, AttributeSet set, int[] attrs) { 183b6086751979cb14740815502597e9fcfddb7054aztenghui if (theme == null) { 184b6086751979cb14740815502597e9fcfddb7054aztenghui return res.obtainAttributes(set, attrs); 185b6086751979cb14740815502597e9fcfddb7054aztenghui } 186b6086751979cb14740815502597e9fcfddb7054aztenghui return theme.obtainStyledAttributes(set, attrs, 0, 0); 187b6086751979cb14740815502597e9fcfddb7054aztenghui } 188b6086751979cb14740815502597e9fcfddb7054aztenghui 189b6086751979cb14740815502597e9fcfddb7054aztenghui /** 190a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * @return a boolean value of {@code index}. If it does not exist, a boolean value of 191a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * {@code fallbackIndex}. If it still does not exist, {@code defaultValue}. 192a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki */ 193a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki public static boolean getBoolean(TypedArray a, @StyleableRes int index, 194a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki @StyleableRes int fallbackIndex, boolean defaultValue) { 195a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki boolean val = a.getBoolean(fallbackIndex, defaultValue); 196a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki return a.getBoolean(index, val); 197a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 198a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki 199a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki /** 200a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * @return a drawable value of {@code index}. If it does not exist, a drawable value of 201a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * {@code fallbackIndex}. If it still does not exist, {@code null}. 202a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki */ 203a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki public static Drawable getDrawable(TypedArray a, @StyleableRes int index, 204a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki @StyleableRes int fallbackIndex) { 205a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki Drawable val = a.getDrawable(index); 206a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki if (val == null) { 207a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki val = a.getDrawable(fallbackIndex); 208a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 209a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki return val; 210a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 211a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki 212a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki /** 213a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * @return an int value of {@code index}. If it does not exist, an int value of 214a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * {@code fallbackIndex}. If it still does not exist, {@code defaultValue}. 215a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki */ 216a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki public static int getInt(TypedArray a, @StyleableRes int index, 217a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki @StyleableRes int fallbackIndex, int defaultValue) { 218a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki int val = a.getInt(fallbackIndex, defaultValue); 219a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki return a.getInt(index, val); 220a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 221a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki 222a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki /** 223a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * @return a resource ID value of {@code index}. If it does not exist, a resource ID value of 224a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * {@code fallbackIndex}. If it still does not exist, {@code defaultValue}. 225a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki */ 226a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki @AnyRes 227a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki public static int getResourceId(TypedArray a, @StyleableRes int index, 228a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki @StyleableRes int fallbackIndex, @AnyRes int defaultValue) { 229a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki int val = a.getResourceId(fallbackIndex, defaultValue); 230a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki return a.getResourceId(index, val); 231a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 232a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki 233a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki /** 234a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * @return a string value of {@code index}. If it does not exist, a string value of 235a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * {@code fallbackIndex}. If it still does not exist, {@code null}. 236a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki */ 237a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki public static String getString(TypedArray a, @StyleableRes int index, 238a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki @StyleableRes int fallbackIndex) { 239a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki String val = a.getString(index); 240a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki if (val == null) { 241a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki val = a.getString(fallbackIndex); 242a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 243a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki return val; 244a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 245a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki 246a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki /** 247a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * Retrieves a text attribute value with the specified fallback ID. 248a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * 249a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * @return a text value of {@code index}. If it does not exist, a text value of 250a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * {@code fallbackIndex}. If it still does not exist, {@code null}. 251a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki */ 252a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki public static CharSequence getText(TypedArray a, @StyleableRes int index, 253a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki @StyleableRes int fallbackIndex) { 254a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki CharSequence val = a.getText(index); 255a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki if (val == null) { 256a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki val = a.getText(fallbackIndex); 257a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 258a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki return val; 259a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 260a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki 261a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki /** 262a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * Retrieves a string array attribute value with the specified fallback ID. 263a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * 264a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * @return a string array value of {@code index}. If it does not exist, a string array value 265a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * of {@code fallbackIndex}. If it still does not exist, {@code null}. 266a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki */ 267a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki public static CharSequence[] getTextArray(TypedArray a, @StyleableRes int index, 268a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki @StyleableRes int fallbackIndex) { 269a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki CharSequence[] val = a.getTextArray(index); 270a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki if (val == null) { 271a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki val = a.getTextArray(fallbackIndex); 272a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 273a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki return val; 274a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 275a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki 276a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki /** 277a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * @return The resource ID value in the {@code context} specified by {@code attr}. If it does 278a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki * not exist, {@code fallbackAttr}. 279a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki */ 280a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki public static int getAttr(Context context, int attr, int fallbackAttr) { 281a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki TypedValue value = new TypedValue(); 282a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki context.getTheme().resolveAttribute(attr, value, true); 283a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki if (value.resourceId != 0) { 284a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki return attr; 285a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 286a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki return fallbackAttr; 287a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki } 288a80878dec1a3689e6e79566a9650de39c3291c01Yuichi Araki} 289