DrawableWrapper.java revision a12962207155305da44b5a1b8fb9acaed358c14c
1a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette/* 2a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * Copyright (C) 2015 The Android Open Source Project 3a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * 4a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * Licensed under the Apache License, Version 2.0 (the "License"); 5a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * you may not use this file except in compliance with the License. 6a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * You may obtain a copy of the License at 7a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * 8a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * http://www.apache.org/licenses/LICENSE-2.0 9a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * 10a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * Unless required by applicable law or agreed to in writing, software 11a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * distributed under the License is distributed on an "AS IS" BASIS, 12a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * See the License for the specific language governing permissions and 14a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * limitations under the License. 15a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette */ 16a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 17a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverettepackage android.graphics.drawable; 18a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 19a12962207155305da44b5a1b8fb9acaed358c14cAlan Viveretteimport org.xmlpull.v1.XmlPullParser; 20a12962207155305da44b5a1b8fb9acaed358c14cAlan Viveretteimport org.xmlpull.v1.XmlPullParserException; 21a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 22a12962207155305da44b5a1b8fb9acaed358c14cAlan Viveretteimport android.annotation.NonNull; 23a12962207155305da44b5a1b8fb9acaed358c14cAlan Viveretteimport android.annotation.Nullable; 24a12962207155305da44b5a1b8fb9acaed358c14cAlan Viveretteimport android.content.res.ColorStateList; 25a12962207155305da44b5a1b8fb9acaed358c14cAlan Viveretteimport android.content.res.Resources; 26a12962207155305da44b5a1b8fb9acaed358c14cAlan Viveretteimport android.content.res.TypedArray; 27a12962207155305da44b5a1b8fb9acaed358c14cAlan Viveretteimport android.graphics.Bitmap; 28a12962207155305da44b5a1b8fb9acaed358c14cAlan Viveretteimport android.graphics.Canvas; 29a12962207155305da44b5a1b8fb9acaed358c14cAlan Viveretteimport android.graphics.ColorFilter; 30a12962207155305da44b5a1b8fb9acaed358c14cAlan Viveretteimport android.graphics.Insets; 31a12962207155305da44b5a1b8fb9acaed358c14cAlan Viveretteimport android.graphics.Outline; 32a12962207155305da44b5a1b8fb9acaed358c14cAlan Viveretteimport android.graphics.PixelFormat; 33a12962207155305da44b5a1b8fb9acaed358c14cAlan Viveretteimport android.graphics.PorterDuff; 34a12962207155305da44b5a1b8fb9acaed358c14cAlan Viveretteimport android.graphics.Rect; 35a12962207155305da44b5a1b8fb9acaed358c14cAlan Viveretteimport android.util.AttributeSet; 36a12962207155305da44b5a1b8fb9acaed358c14cAlan Viveretteimport android.view.View; 37a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 38a12962207155305da44b5a1b8fb9acaed358c14cAlan Viveretteimport java.io.IOException; 39a12962207155305da44b5a1b8fb9acaed358c14cAlan Viveretteimport java.util.Collection; 40a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 41a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette/** 42a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * Drawable container with only one child element. 43a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette */ 44a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverettepublic abstract class DrawableWrapper extends Drawable implements Drawable.Callback { 45a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette private DrawableWrapperState mState; 46a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette private Drawable mDrawable; 47a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette private boolean mMutated; 48a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 49a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette DrawableWrapper(DrawableWrapperState state, Resources res) { 50a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mState = state; 51a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 52a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette updateLocalState(res); 53a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 54a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 55a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette /** 56a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * Creates a new wrapper around the specified drawable. 57a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * 58a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * @param dr the drawable to wrap 59a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette */ 60a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public DrawableWrapper(@Nullable Drawable dr) { 61a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mState = null; 62a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mDrawable = dr; 63a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 64a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 65a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette /** 66a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * Initializes local dynamic properties from state. This should be called 67a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * after significant state changes, e.g. from the One True Constructor and 68a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * after inflating or applying a theme. 69a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette */ 70a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette private void updateLocalState(Resources res) { 71a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (mState != null && mState.mDrawableState != null) { 72a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette final Drawable dr = mState.mDrawableState.newDrawable(res); 73a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette setDrawable(dr); 74a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 75a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 76a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 77a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette /** 78a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * Sets the wrapped drawable. 79a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * 80a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * @param dr the wrapped drawable 81a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette */ 82a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public void setDrawable(@Nullable Drawable dr) { 83a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (mDrawable != null) { 84a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mDrawable.setCallback(null); 85a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 86a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 87a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mDrawable = dr; 88a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 89a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (dr != null) { 90a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette dr.setCallback(this); 91a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 92a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette // Only call setters for data that's stored in the base Drawable. 93a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette dr.setVisible(isVisible(), true); 94a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette dr.setState(getState()); 95a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette dr.setLevel(getLevel()); 96a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette dr.setBounds(getBounds()); 97a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette dr.setLayoutDirection(getLayoutDirection()); 98a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 99a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (mState != null) { 100a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mState.mDrawableState = dr.getConstantState(); 101a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 102a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 103a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 104a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette invalidateSelf(); 105a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 106a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 107a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette /** 108a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * @return the wrapped drawable 109a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette */ 110a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Nullable 111a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public Drawable getDrawable() { 112a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return mDrawable; 113a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 114a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 115a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette void updateStateFromTypedArray(TypedArray a) { 116a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette final DrawableWrapperState state = mState; 117a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (state == null) { 118a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return; 119a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 120a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 121a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette // Account for any configuration changes. 122a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette state.mChangingConfigurations |= a.getChangingConfigurations(); 123a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 124a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette // Extract the theme attributes, if any. 125a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette state.mThemeAttrs = a.extractThemeAttrs(); 126a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 127a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette // TODO: Consider using R.styleable.DrawableWrapper_drawable 128a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 129a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 130a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 131a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public void applyTheme(Resources.Theme t) { 132a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette super.applyTheme(t); 133a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 134a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette final DrawableWrapperState state = mState; 135a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (state == null) { 136a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return; 137a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 138a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 139a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (mDrawable != null && mDrawable.canApplyTheme()) { 140a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mDrawable.applyTheme(t); 141a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 142a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 143a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 144a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 145a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public boolean canApplyTheme() { 146a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return (mState != null && mState.canApplyTheme()) || super.canApplyTheme(); 147a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 148a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 149a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 150a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public void invalidateDrawable(Drawable who) { 151a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette final Callback callback = getCallback(); 152a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (callback != null) { 153a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette callback.invalidateDrawable(this); 154a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 155a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 156a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 157a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 158a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public void scheduleDrawable(Drawable who, Runnable what, long when) { 159a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette final Callback callback = getCallback(); 160a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (callback != null) { 161a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette callback.scheduleDrawable(this, what, when); 162a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 163a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 164a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 165a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 166a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public void unscheduleDrawable(Drawable who, Runnable what) { 167a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette final Callback callback = getCallback(); 168a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (callback != null) { 169a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette callback.unscheduleDrawable(this, what); 170a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 171a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 172a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 173a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 174a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public void draw(@NonNull Canvas canvas) { 175a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (mDrawable != null) { 176a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mDrawable.draw(canvas); 177a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 178a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 179a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 180a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 181a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public int getChangingConfigurations() { 182a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return super.getChangingConfigurations() 183a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette | (mState != null ? mState.mChangingConfigurations : 0) 184a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette | mDrawable.getChangingConfigurations(); 185a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 186a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 187a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 188a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public boolean getPadding(@NonNull Rect padding) { 189a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return mDrawable != null && mDrawable.getPadding(padding); 190a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 191a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 192a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette /** @hide */ 193a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 194a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public Insets getOpticalInsets() { 195a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return mDrawable != null ? mDrawable.getOpticalInsets() : Insets.NONE; 196a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 197a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 198a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 199a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public void setHotspot(float x, float y) { 200a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (mDrawable != null) { 201a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mDrawable.setHotspot(x, y); 202a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 203a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 204a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 205a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 206a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public void setHotspotBounds(int left, int top, int right, int bottom) { 207a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (mDrawable != null) { 208a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mDrawable.setHotspotBounds(left, top, right, bottom); 209a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 210a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 211a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 212a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 213a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public void getHotspotBounds(@NonNull Rect outRect) { 214a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (mDrawable != null) { 215a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mDrawable.getHotspotBounds(outRect); 216a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } else { 217a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette outRect.set(getBounds()); 218a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 219a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 220a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 221a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 222a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public boolean setVisible(boolean visible, boolean restart) { 223a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette final boolean superChanged = super.setVisible(visible, restart); 224a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette final boolean changed = mDrawable != null && mDrawable.setVisible(visible, restart); 225a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return superChanged | changed; 226a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 227a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 228a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 229a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public void setAlpha(int alpha) { 230a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (mDrawable != null) { 231a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mDrawable.setAlpha(alpha); 232a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 233a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 234a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 235a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 236a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public int getAlpha() { 237a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return mDrawable != null ? mDrawable.getAlpha() : 255; 238a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 239a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 240a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 241a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public void setColorFilter(@Nullable ColorFilter cf) { 242a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (mDrawable != null) { 243a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mDrawable.setColorFilter(cf); 244a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 245a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 246a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 247a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 248a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public void setTintList(@Nullable ColorStateList tint) { 249a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (mDrawable != null) { 250a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mDrawable.setTintList(tint); 251a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 252a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 253a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 254a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 255a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public void setTintMode(@Nullable PorterDuff.Mode tintMode) { 256a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (mDrawable != null) { 257a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mDrawable.setTintMode(tintMode); 258a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 259a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 260a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 261a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 262a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public boolean onLayoutDirectionChange(@View.ResolvedLayoutDir int layoutDirection) { 263a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return mDrawable != null && mDrawable.setLayoutDirection(layoutDirection); 264a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 265a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 266a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 267a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public int getOpacity() { 268a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return mDrawable != null ? mDrawable.getOpacity() : PixelFormat.TRANSPARENT; 269a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 270a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 271a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 272a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public boolean isStateful() { 273a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return mDrawable != null && mDrawable.isStateful(); 274a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 275a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 276a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 277a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette protected boolean onStateChange(int[] state) { 278a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (mDrawable != null) { 279a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette final boolean changed = mDrawable.setState(state); 280a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (changed) { 281a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette onBoundsChange(getBounds()); 282a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 283a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return changed; 284a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 285a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return false; 286a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 287a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 288a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 289a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette protected boolean onLevelChange(int level) { 290a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return mDrawable != null && mDrawable.setLevel(level); 291a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 292a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 293a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 294a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette protected void onBoundsChange(@NonNull Rect bounds) { 295a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (mDrawable != null) { 296a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mDrawable.setBounds(bounds); 297a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 298a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 299a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 300a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 301a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public int getIntrinsicWidth() { 302a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return mDrawable != null ? mDrawable.getIntrinsicWidth() : -1; 303a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 304a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 305a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 306a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public int getIntrinsicHeight() { 307a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return mDrawable != null ? mDrawable.getIntrinsicHeight() : -1; 308a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 309a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 310a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 311a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public void getOutline(@NonNull Outline outline) { 312a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (mDrawable != null) { 313a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mDrawable.getOutline(outline); 314a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } else { 315a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette super.getOutline(outline); 316a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 317a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 318a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 319a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 320a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Nullable 321a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public ConstantState getConstantState() { 322a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (mState != null && mState.canConstantState()) { 323a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mState.mChangingConfigurations = getChangingConfigurations(); 324a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return mState; 325a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 326a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return null; 327a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 328a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 329a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 330a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @NonNull 331a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public Drawable mutate() { 332a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (!mMutated && super.mutate() == this) { 333a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mState = mutateConstantState(); 334a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (mDrawable != null) { 335a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mDrawable.mutate(); 336a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 337a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (mState != null) { 338a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mState.mDrawableState = mDrawable != null ? mDrawable.getConstantState() : null; 339a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 340a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mMutated = true; 341a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 342a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return this; 343a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 344a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 345a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette /** 346a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * Mutates the constant state and returns the new state. Responsible for 347a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * updating any local copy. 348a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * <p> 349a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * This method should never call the super implementation; it should always 350a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * mutate and return its own constant state. 351a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * 352a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * @return the new state 353a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette */ 354a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette DrawableWrapperState mutateConstantState() { 355a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return mState; 356a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 357a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 358a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette /** 359a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * @hide Only used by the framework for pre-loading resources. 360a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette */ 361a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public void clearMutated() { 362a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette super.clearMutated(); 363a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (mDrawable != null) { 364a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mDrawable.clearMutated(); 365a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 366a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mMutated = false; 367a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 368a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 369a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette /** 370a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette * Called during inflation to inflate the child element. 371a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette */ 372a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette void inflateChildDrawable(Resources r, XmlPullParser parser, AttributeSet attrs, 373a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette Resources.Theme theme) throws XmlPullParserException, IOException { 374a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette // Drawable specified on the root element takes precedence. 375a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (getDrawable() != null) { 376a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return; 377a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 378a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 379a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette // Seek to the first child element. 380a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette Drawable dr = null; 381a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette int type; 382a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette final int outerDepth = parser.getDepth(); 383a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 384a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 385a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (type == XmlPullParser.START_TAG) { 386a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette dr = Drawable.createFromXmlInner(r, parser, attrs, theme); 387a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette break; 388a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 389a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 390a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 391a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (dr != null) { 392a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette setDrawable(dr); 393a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 394a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 395a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 396a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette abstract static class DrawableWrapperState extends Drawable.ConstantState { 397a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette int[] mThemeAttrs; 398a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette int mChangingConfigurations; 399a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 400a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette Drawable.ConstantState mDrawableState; 401a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 402a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette DrawableWrapperState(DrawableWrapperState orig) { 403a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (orig != null) { 404a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mThemeAttrs = orig.mThemeAttrs; 405a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mChangingConfigurations = orig.mChangingConfigurations; 406a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette mDrawableState = orig.mDrawableState; 407a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 408a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 409a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 410a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 411a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public boolean canApplyTheme() { 412a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return mThemeAttrs != null 413a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette || (mDrawableState != null && mDrawableState.canApplyTheme()) 414a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette || super.canApplyTheme(); 415a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 416a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 417a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 418a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public int addAtlasableBitmaps(Collection<Bitmap> atlasList) { 419a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette final Drawable.ConstantState state = mDrawableState; 420a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette if (state != null) { 421a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return state.addAtlasableBitmaps(atlasList); 422a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 423a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return 0; 424a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 425a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 426a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 427a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public Drawable newDrawable() { 428a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return newDrawable(null); 429a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 430a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 431a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 432a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public abstract Drawable newDrawable(Resources res); 433a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 434a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette @Override 435a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public int getChangingConfigurations() { 436a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return mChangingConfigurations; 437a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 438a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette 439a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette public boolean canConstantState() { 440a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette return mDrawableState != null; 441a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 442a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette } 443a12962207155305da44b5a1b8fb9acaed358c14cAlan Viverette} 444