DrawableWrapper.java revision 860126b78aa4d6e8db5208c7f96764a8556cf95f
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.graphics.drawable; 18 19import android.content.res.Resources; 20import android.graphics.Canvas; 21import android.graphics.ColorFilter; 22import android.graphics.Rect; 23import android.graphics.Xfermode; 24 25/** 26 * A Drawable that wraps another Drawable. 27 */ 28public class DrawableWrapper extends Drawable implements Drawable.Callback { 29 private WrapperState mWrapperState; 30 31 /** Local drawable backed by its own constant state. */ 32 private Drawable mWrappedDrawable; 33 34 private boolean mMutated; 35 36 /** @hide */ 37 @Override 38 public boolean isProjected() { 39 return mWrappedDrawable.isProjected(); 40 } 41 42 @Override 43 public void setAutoMirrored(boolean mirrored) { 44 mWrappedDrawable.setAutoMirrored(mirrored); 45 } 46 47 @Override 48 public boolean isAutoMirrored() { 49 return mWrappedDrawable.isAutoMirrored(); 50 } 51 52 @Override 53 public int getMinimumWidth() { 54 return mWrappedDrawable.getMinimumWidth(); 55 } 56 57 @Override 58 public int getMinimumHeight() { 59 return mWrappedDrawable.getMinimumHeight(); 60 } 61 62 @Override 63 public int getIntrinsicWidth() { 64 return mWrappedDrawable.getIntrinsicWidth(); 65 } 66 67 @Override 68 public int getIntrinsicHeight() { 69 return mWrappedDrawable.getIntrinsicHeight(); 70 } 71 72 @Override 73 public Drawable getCurrent() { 74 return mWrappedDrawable.getCurrent(); 75 } 76 77 @Override 78 public void invalidateDrawable(Drawable who) { 79 final Callback callback = getCallback(); 80 if (callback != null) { 81 callback.invalidateDrawable(this); 82 } 83 } 84 85 @Override 86 public void scheduleDrawable(Drawable who, Runnable what, long when) { 87 final Callback callback = getCallback(); 88 if (callback != null) { 89 callback.scheduleDrawable(this, what, when); 90 } 91 } 92 93 @Override 94 public void unscheduleDrawable(Drawable who, Runnable what) { 95 final Callback callback = getCallback(); 96 if (callback != null) { 97 callback.unscheduleDrawable(this, what); 98 } 99 } 100 101 @Override 102 public void draw(Canvas canvas) { 103 mWrappedDrawable.draw(canvas); 104 } 105 106 @Override 107 public int getChangingConfigurations() { 108 return mWrappedDrawable.getChangingConfigurations(); 109 } 110 111 @Override 112 public boolean getPadding(Rect padding) { 113 return mWrappedDrawable.getPadding(padding); 114 } 115 116 @Override 117 public Rect getDirtyBounds() { 118 return mWrappedDrawable.getDirtyBounds(); 119 } 120 121 @Override 122 public boolean supportsHotspots() { 123 return mWrappedDrawable.supportsHotspots(); 124 } 125 126 @Override 127 public void setHotspot(int id, float x, float y) { 128 mWrappedDrawable.setHotspot(id, x, y); 129 } 130 131 @Override 132 public void removeHotspot(int id) { 133 mWrappedDrawable.removeHotspot(id); 134 } 135 136 @Override 137 public void clearHotspots() { 138 mWrappedDrawable.clearHotspots(); 139 } 140 141 @Override 142 public boolean setVisible(boolean visible, boolean restart) { 143 // Must call through to super(). 144 super.setVisible(visible, restart); 145 return mWrappedDrawable.setVisible(visible, restart); 146 } 147 148 @Override 149 public void setAlpha(int alpha) { 150 mWrappedDrawable.setAlpha(alpha); 151 } 152 153 @Override 154 public int getAlpha() { 155 return mWrappedDrawable.getAlpha(); 156 } 157 158 /** {@hide} */ 159 @Override 160 public void setLayoutDirection(int layoutDirection) { 161 mWrappedDrawable.setLayoutDirection(layoutDirection); 162 } 163 164 /** {@hide} */ 165 @Override 166 public int getLayoutDirection() { 167 return mWrappedDrawable.getLayoutDirection(); 168 } 169 170 @Override 171 public void setColorFilter(ColorFilter cf) { 172 mWrappedDrawable.setColorFilter(cf); 173 } 174 175 @Override 176 public ColorFilter getColorFilter() { 177 return mWrappedDrawable.getColorFilter(); 178 } 179 180 @Override 181 public void setFilterBitmap(boolean filter) { 182 mWrappedDrawable.setFilterBitmap(filter); 183 } 184 185 @Override 186 public void setXfermode(Xfermode mode) { 187 mWrappedDrawable.setXfermode(mode); 188 } 189 190 @Override 191 public int getOpacity() { 192 return mWrappedDrawable.getOpacity(); 193 } 194 195 @Override 196 public boolean isStateful() { 197 return mWrappedDrawable.isStateful(); 198 } 199 200 @Override 201 public final boolean setState(int[] stateSet) { 202 return super.setState(stateSet); 203 } 204 205 @Override 206 public final int[] getState() { 207 return super.getState(); 208 } 209 210 @Override 211 protected boolean onStateChange(int[] state) { 212 // Don't override setState(), getState(). 213 return mWrappedDrawable.setState(state); 214 } 215 216 @Override 217 protected boolean onLevelChange(int level) { 218 // Don't override setLevel(), getLevel(). 219 return mWrappedDrawable.setLevel(level); 220 } 221 222 @Override 223 public final void setBounds(int left, int top, int right, int bottom) { 224 super.setBounds(left, top, right, bottom); 225 } 226 227 @Override 228 public final void setBounds(Rect bounds) { 229 super.setBounds(bounds); 230 } 231 232 @Override 233 protected void onBoundsChange(Rect bounds) { 234 // Don't override setBounds(), getBounds(). 235 mWrappedDrawable.setBounds(bounds); 236 } 237 238 protected void setConstantState(WrapperState wrapperState, Resources res) { 239 mWrapperState = wrapperState; 240 241 // Load a new drawable from the constant state. 242 if (wrapperState == null || wrapperState.mWrappedConstantState == null) { 243 mWrappedDrawable = null; 244 } else if (res != null) { 245 mWrappedDrawable = wrapperState.mWrappedConstantState.newDrawable(res); 246 } else { 247 mWrappedDrawable = wrapperState.mWrappedConstantState.newDrawable(); 248 } 249 } 250 251 @Override 252 public ConstantState getConstantState() { 253 return mWrapperState; 254 } 255 256 @Override 257 public Drawable mutate() { 258 if (!mMutated) { 259 mWrappedDrawable = mWrappedDrawable.mutate(); 260 mMutated = true; 261 } 262 return this; 263 } 264 265 /** 266 * Sets the wrapped drawable and update the constant state. 267 * 268 * @param drawable 269 * @param res 270 */ 271 protected final void setDrawable(Drawable drawable, Resources res) { 272 if (mWrappedDrawable != null) { 273 mWrappedDrawable.setCallback(null); 274 } 275 276 mWrappedDrawable = drawable; 277 278 if (drawable != null) { 279 drawable.setCallback(this); 280 281 mWrapperState.mWrappedConstantState = drawable.getConstantState(); 282 } else { 283 mWrapperState.mWrappedConstantState = null; 284 } 285 } 286 287 protected final Drawable getDrawable() { 288 return mWrappedDrawable; 289 } 290 291 public static abstract class WrapperState extends ConstantState { 292 ConstantState mWrappedConstantState; 293 294 WrapperState(WrapperState orig) { 295 if (orig != null) { 296 mWrappedConstantState = orig.mWrappedConstantState; 297 } 298 } 299 300 @Override 301 public int getChangingConfigurations() { 302 return mWrappedConstantState.getChangingConfigurations(); 303 } 304 } 305} 306