1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.support.v7.widget; 18 19import android.content.Context; 20import android.content.res.ColorStateList; 21import android.content.res.Resources; 22import android.content.res.TypedArray; 23import android.graphics.drawable.Drawable; 24import android.os.Build; 25import android.support.v7.content.res.AppCompatResources; 26import android.util.AttributeSet; 27import android.util.TypedValue; 28 29/** 30 * A class that wraps a {@link android.content.res.TypedArray} and provides the same public API 31 * surface. The purpose of this class is so that we can intercept the {@link #getDrawable(int)} 32 * call and tint the result. 33 * 34 * @hide 35 */ 36public class TintTypedArray { 37 38 private final Context mContext; 39 private final TypedArray mWrapped; 40 41 private TypedValue mTypedValue; 42 43 public static TintTypedArray obtainStyledAttributes(Context context, AttributeSet set, 44 int[] attrs) { 45 return new TintTypedArray(context, context.obtainStyledAttributes(set, attrs)); 46 } 47 48 public static TintTypedArray obtainStyledAttributes(Context context, AttributeSet set, 49 int[] attrs, int defStyleAttr, int defStyleRes) { 50 return new TintTypedArray(context, 51 context.obtainStyledAttributes(set, attrs, defStyleAttr, defStyleRes)); 52 } 53 54 public static TintTypedArray obtainStyledAttributes(Context context, int resid, int[] attrs) { 55 return new TintTypedArray(context, context.obtainStyledAttributes(resid, attrs)); 56 } 57 58 private TintTypedArray(Context context, TypedArray array) { 59 mContext = context; 60 mWrapped = array; 61 } 62 63 public Drawable getDrawable(int index) { 64 if (mWrapped.hasValue(index)) { 65 final int resourceId = mWrapped.getResourceId(index, 0); 66 if (resourceId != 0) { 67 return AppCompatDrawableManager.get().getDrawable(mContext, resourceId); 68 } 69 } 70 return mWrapped.getDrawable(index); 71 } 72 73 public Drawable getDrawableIfKnown(int index) { 74 if (mWrapped.hasValue(index)) { 75 final int resourceId = mWrapped.getResourceId(index, 0); 76 if (resourceId != 0) { 77 return AppCompatDrawableManager.get().getDrawable(mContext, resourceId, true); 78 } 79 } 80 return null; 81 } 82 83 public int length() { 84 return mWrapped.length(); 85 } 86 87 public int getIndexCount() { 88 return mWrapped.getIndexCount(); 89 } 90 91 public int getIndex(int at) { 92 return mWrapped.getIndex(at); 93 } 94 95 public Resources getResources() { 96 return mWrapped.getResources(); 97 } 98 99 public CharSequence getText(int index) { 100 return mWrapped.getText(index); 101 } 102 103 public String getString(int index) { 104 return mWrapped.getString(index); 105 } 106 107 public String getNonResourceString(int index) { 108 return mWrapped.getNonResourceString(index); 109 } 110 111 public boolean getBoolean(int index, boolean defValue) { 112 return mWrapped.getBoolean(index, defValue); 113 } 114 115 public int getInt(int index, int defValue) { 116 return mWrapped.getInt(index, defValue); 117 } 118 119 public float getFloat(int index, float defValue) { 120 return mWrapped.getFloat(index, defValue); 121 } 122 123 public int getColor(int index, int defValue) { 124 return mWrapped.getColor(index, defValue); 125 } 126 127 public ColorStateList getColorStateList(int index) { 128 if (mWrapped.hasValue(index)) { 129 final int resourceId = mWrapped.getResourceId(index, 0); 130 if (resourceId != 0) { 131 final ColorStateList value = 132 AppCompatResources.getColorStateList(mContext, resourceId); 133 if (value != null) { 134 return value; 135 } 136 } 137 } 138 return mWrapped.getColorStateList(index); 139 } 140 141 public int getInteger(int index, int defValue) { 142 return mWrapped.getInteger(index, defValue); 143 } 144 145 public float getDimension(int index, float defValue) { 146 return mWrapped.getDimension(index, defValue); 147 } 148 149 public int getDimensionPixelOffset(int index, int defValue) { 150 return mWrapped.getDimensionPixelOffset(index, defValue); 151 } 152 153 public int getDimensionPixelSize(int index, int defValue) { 154 return mWrapped.getDimensionPixelSize(index, defValue); 155 } 156 157 public int getLayoutDimension(int index, String name) { 158 return mWrapped.getLayoutDimension(index, name); 159 } 160 161 public int getLayoutDimension(int index, int defValue) { 162 return mWrapped.getLayoutDimension(index, defValue); 163 } 164 165 public float getFraction(int index, int base, int pbase, float defValue) { 166 return mWrapped.getFraction(index, base, pbase, defValue); 167 } 168 169 public int getResourceId(int index, int defValue) { 170 return mWrapped.getResourceId(index, defValue); 171 } 172 173 public CharSequence[] getTextArray(int index) { 174 return mWrapped.getTextArray(index); 175 } 176 177 public boolean getValue(int index, TypedValue outValue) { 178 return mWrapped.getValue(index, outValue); 179 } 180 181 public int getType(int index) { 182 if (Build.VERSION.SDK_INT >= 21) { 183 return mWrapped.getType(index); 184 } else { 185 if (mTypedValue == null) { 186 mTypedValue = new TypedValue(); 187 } 188 mWrapped.getValue(index, mTypedValue); 189 return mTypedValue.type; 190 } 191 } 192 193 public boolean hasValue(int index) { 194 return mWrapped.hasValue(index); 195 } 196 197 public TypedValue peekValue(int index) { 198 return mWrapped.peekValue(index); 199 } 200 201 public String getPositionDescription() { 202 return mWrapped.getPositionDescription(); 203 } 204 205 public void recycle() { 206 mWrapped.recycle(); 207 } 208 209 public int getChangingConfigurations() { 210 return mWrapped.getChangingConfigurations(); 211 } 212 213} 214