19840efe3dbdc7026521da8576574c55120782f6cChris Banes/* 29840efe3dbdc7026521da8576574c55120782f6cChris Banes * Copyright (C) 2015 The Android Open Source Project 39840efe3dbdc7026521da8576574c55120782f6cChris Banes * 49840efe3dbdc7026521da8576574c55120782f6cChris Banes * Licensed under the Apache License, Version 2.0 (the "License"); 59840efe3dbdc7026521da8576574c55120782f6cChris Banes * you may not use this file except in compliance with the License. 69840efe3dbdc7026521da8576574c55120782f6cChris Banes * You may obtain a copy of the License at 79840efe3dbdc7026521da8576574c55120782f6cChris Banes * 89840efe3dbdc7026521da8576574c55120782f6cChris Banes * http://www.apache.org/licenses/LICENSE-2.0 99840efe3dbdc7026521da8576574c55120782f6cChris Banes * 109840efe3dbdc7026521da8576574c55120782f6cChris Banes * Unless required by applicable law or agreed to in writing, software 119840efe3dbdc7026521da8576574c55120782f6cChris Banes * distributed under the License is distributed on an "AS IS" BASIS, 129840efe3dbdc7026521da8576574c55120782f6cChris Banes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139840efe3dbdc7026521da8576574c55120782f6cChris Banes * See the License for the specific language governing permissions and 149840efe3dbdc7026521da8576574c55120782f6cChris Banes * limitations under the License. 159840efe3dbdc7026521da8576574c55120782f6cChris Banes */ 169840efe3dbdc7026521da8576574c55120782f6cChris Banes 179840efe3dbdc7026521da8576574c55120782f6cChris Banespackage android.support.design.widget; 189840efe3dbdc7026521da8576574c55120782f6cChris Banes 19b3f442095596ede223227f6ae7afff6a3170e118Kirill Grouchnikovimport android.animation.Animator; 20f0aec033caa46d2cdddad020b8748d24f921ad5bChris Banesimport android.animation.AnimatorSet; 219840efe3dbdc7026521da8576574c55120782f6cChris Banesimport android.animation.ObjectAnimator; 229840efe3dbdc7026521da8576574c55120782f6cChris Banesimport android.animation.StateListAnimator; 239840efe3dbdc7026521da8576574c55120782f6cChris Banesimport android.content.res.ColorStateList; 249840efe3dbdc7026521da8576574c55120782f6cChris Banesimport android.graphics.PorterDuff; 256d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banesimport android.graphics.Rect; 269840efe3dbdc7026521da8576574c55120782f6cChris Banesimport android.graphics.drawable.Drawable; 271c4d0c9dec028624cd661be53e68b1464b14ab7fChris Banesimport android.graphics.drawable.GradientDrawable; 286d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banesimport android.graphics.drawable.InsetDrawable; 29cd78954a2b32d9c22686f12c194fac7e49566cf6Chris Banesimport android.graphics.drawable.LayerDrawable; 309840efe3dbdc7026521da8576574c55120782f6cChris Banesimport android.graphics.drawable.RippleDrawable; 31829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanuimport android.os.Build; 328f886fe8c7e23fe6ccb8734167c960c2ed3429c3Alan Viveretteimport android.support.annotation.RequiresApi; 337e82b99953680915596eaf0eb35927388e574ca8Chris Banesimport android.support.v4.graphics.drawable.DrawableCompat; 34f0aec033caa46d2cdddad020b8748d24f921ad5bChris Banesimport android.view.View; 359840efe3dbdc7026521da8576574c55120782f6cChris Banes 36b3f442095596ede223227f6ae7afff6a3170e118Kirill Grouchnikovimport java.util.ArrayList; 37b3f442095596ede223227f6ae7afff6a3170e118Kirill Grouchnikovimport java.util.List; 38b3f442095596ede223227f6ae7afff6a3170e118Kirill Grouchnikov 398f886fe8c7e23fe6ccb8734167c960c2ed3429c3Alan Viverette@RequiresApi(21) 40522c70ab180af24bf9777cec0a1a9b804c77c8d9Aurimas Liutikasclass FloatingActionButtonLollipop extends FloatingActionButtonImpl { 419840efe3dbdc7026521da8576574c55120782f6cChris Banes 426d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes private InsetDrawable mInsetDrawable; 439840efe3dbdc7026521da8576574c55120782f6cChris Banes 44fc780bab91bd4275ae2c3b75c3dfb327e008e4dbChris Banes FloatingActionButtonLollipop(VisibilityAwareImageButton view, 45ae7189188acb2bc972b08d9fbd59939f341c7829Aurimas Liutikas ShadowViewDelegate shadowViewDelegate) { 46ae7189188acb2bc972b08d9fbd59939f341c7829Aurimas Liutikas super(view, shadowViewDelegate); 479840efe3dbdc7026521da8576574c55120782f6cChris Banes } 489840efe3dbdc7026521da8576574c55120782f6cChris Banes 499840efe3dbdc7026521da8576574c55120782f6cChris Banes @Override 50097e80a3c5518c6bf2e9f3f9b55ed9f4b5cc37e8Chris Banes void setBackgroundDrawable(ColorStateList backgroundTint, 51cd78954a2b32d9c22686f12c194fac7e49566cf6Chris Banes PorterDuff.Mode backgroundTintMode, int rippleColor, int borderWidth) { 52097e80a3c5518c6bf2e9f3f9b55ed9f4b5cc37e8Chris Banes // Now we need to tint the shape background with the tint 53097e80a3c5518c6bf2e9f3f9b55ed9f4b5cc37e8Chris Banes mShapeDrawable = DrawableCompat.wrap(createShapeDrawable()); 547e82b99953680915596eaf0eb35927388e574ca8Chris Banes DrawableCompat.setTintList(mShapeDrawable, backgroundTint); 559840efe3dbdc7026521da8576574c55120782f6cChris Banes if (backgroundTintMode != null) { 567e82b99953680915596eaf0eb35927388e574ca8Chris Banes DrawableCompat.setTintMode(mShapeDrawable, backgroundTintMode); 579840efe3dbdc7026521da8576574c55120782f6cChris Banes } 589840efe3dbdc7026521da8576574c55120782f6cChris Banes 59cd78954a2b32d9c22686f12c194fac7e49566cf6Chris Banes final Drawable rippleContent; 60cd78954a2b32d9c22686f12c194fac7e49566cf6Chris Banes if (borderWidth > 0) { 6180de0674c28a2bd9ade11f24a3b0e46ea83b6847Chris Banes mBorderDrawable = createBorderDrawable(borderWidth, backgroundTint); 6280de0674c28a2bd9ade11f24a3b0e46ea83b6847Chris Banes rippleContent = new LayerDrawable(new Drawable[]{mBorderDrawable, mShapeDrawable}); 63cd78954a2b32d9c22686f12c194fac7e49566cf6Chris Banes } else { 64cd78954a2b32d9c22686f12c194fac7e49566cf6Chris Banes mBorderDrawable = null; 65cd78954a2b32d9c22686f12c194fac7e49566cf6Chris Banes rippleContent = mShapeDrawable; 66cd78954a2b32d9c22686f12c194fac7e49566cf6Chris Banes } 67cd78954a2b32d9c22686f12c194fac7e49566cf6Chris Banes 689840efe3dbdc7026521da8576574c55120782f6cChris Banes mRippleDrawable = new RippleDrawable(ColorStateList.valueOf(rippleColor), 69cd78954a2b32d9c22686f12c194fac7e49566cf6Chris Banes rippleContent, null); 709840efe3dbdc7026521da8576574c55120782f6cChris Banes 713d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes mContentBackground = mRippleDrawable; 723d81c900316412b4130bf40e0dd8b0d3d3a93e78Chris Banes 739840efe3dbdc7026521da8576574c55120782f6cChris Banes mShadowViewDelegate.setBackgroundDrawable(mRippleDrawable); 749840efe3dbdc7026521da8576574c55120782f6cChris Banes } 759840efe3dbdc7026521da8576574c55120782f6cChris Banes 769840efe3dbdc7026521da8576574c55120782f6cChris Banes @Override 779840efe3dbdc7026521da8576574c55120782f6cChris Banes void setRippleColor(int rippleColor) { 788603357c9433b9aef1805413a3bfc4a4f8decc50Chris Banes if (mRippleDrawable instanceof RippleDrawable) { 798603357c9433b9aef1805413a3bfc4a4f8decc50Chris Banes ((RippleDrawable) mRippleDrawable).setColor(ColorStateList.valueOf(rippleColor)); 808603357c9433b9aef1805413a3bfc4a4f8decc50Chris Banes } else { 818603357c9433b9aef1805413a3bfc4a4f8decc50Chris Banes super.setRippleColor(rippleColor); 828603357c9433b9aef1805413a3bfc4a4f8decc50Chris Banes } 839840efe3dbdc7026521da8576574c55120782f6cChris Banes } 849840efe3dbdc7026521da8576574c55120782f6cChris Banes 859840efe3dbdc7026521da8576574c55120782f6cChris Banes @Override 86f0aec033caa46d2cdddad020b8748d24f921ad5bChris Banes void onElevationsChanged(final float elevation, final float pressedTranslationZ) { 87c69882cb9b130902c1554ef5d3e3b06d776cd796Alan Viverette if (Build.VERSION.SDK_INT == 21) { 88829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu // Animations produce NPE in version 21. Bluntly set the values instead (matching the 89829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu // logic in the animations below). 90829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu if (mView.isEnabled()) { 91829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu mView.setElevation(elevation); 92829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu if (mView.isFocused() || mView.isPressed()) { 93829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu mView.setTranslationZ(pressedTranslationZ); 94829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu } else { 95829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu mView.setTranslationZ(0); 96829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu } 97829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu } else { 98829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu mView.setElevation(0); 99829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu mView.setTranslationZ(0); 100829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu } 101829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu } else { 102829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu final StateListAnimator stateListAnimator = new StateListAnimator(); 103829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu 104829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu // Animate elevation and translationZ to our values when pressed 105829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu AnimatorSet set = new AnimatorSet(); 106829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu set.play(ObjectAnimator.ofFloat(mView, "elevation", elevation).setDuration(0)) 107829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu .with(ObjectAnimator.ofFloat(mView, View.TRANSLATION_Z, pressedTranslationZ) 108829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu .setDuration(PRESSED_ANIM_DURATION)); 109829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu set.setInterpolator(ANIM_INTERPOLATOR); 110829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu stateListAnimator.addState(PRESSED_ENABLED_STATE_SET, set); 111829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu 112829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu // Same deal for when we're focused 113829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu set = new AnimatorSet(); 114829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu set.play(ObjectAnimator.ofFloat(mView, "elevation", elevation).setDuration(0)) 115829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu .with(ObjectAnimator.ofFloat(mView, View.TRANSLATION_Z, pressedTranslationZ) 116829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu .setDuration(PRESSED_ANIM_DURATION)); 117829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu set.setInterpolator(ANIM_INTERPOLATOR); 118829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu stateListAnimator.addState(FOCUSED_ENABLED_STATE_SET, set); 119829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu 120829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu // Animate translationZ to 0 if not pressed 121829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu set = new AnimatorSet(); 122b3f442095596ede223227f6ae7afff6a3170e118Kirill Grouchnikov List<Animator> animators = new ArrayList<>(); 123b3f442095596ede223227f6ae7afff6a3170e118Kirill Grouchnikov animators.add(ObjectAnimator.ofFloat(mView, "elevation", elevation).setDuration(0)); 124b3f442095596ede223227f6ae7afff6a3170e118Kirill Grouchnikov if (Build.VERSION.SDK_INT >= 22 && Build.VERSION.SDK_INT <= 24) { 125b3f442095596ede223227f6ae7afff6a3170e118Kirill Grouchnikov // This is a no-op animation which exists here only for introducing the duration 126b3f442095596ede223227f6ae7afff6a3170e118Kirill Grouchnikov // because setting the delay (on the next animation) via "setDelay" or "after" 127b3f442095596ede223227f6ae7afff6a3170e118Kirill Grouchnikov // can trigger a NPE between android versions 22 and 24 (due to a framework 128b3f442095596ede223227f6ae7afff6a3170e118Kirill Grouchnikov // bug). The issue has been fixed in version 25. 129b3f442095596ede223227f6ae7afff6a3170e118Kirill Grouchnikov animators.add(ObjectAnimator.ofFloat(mView, View.TRANSLATION_Z, 130b3f442095596ede223227f6ae7afff6a3170e118Kirill Grouchnikov mView.getTranslationZ()).setDuration(PRESSED_ANIM_DELAY)); 131b3f442095596ede223227f6ae7afff6a3170e118Kirill Grouchnikov } 132b3f442095596ede223227f6ae7afff6a3170e118Kirill Grouchnikov animators.add(ObjectAnimator.ofFloat(mView, View.TRANSLATION_Z, 0f) 133b3f442095596ede223227f6ae7afff6a3170e118Kirill Grouchnikov .setDuration(PRESSED_ANIM_DURATION)); 134b3f442095596ede223227f6ae7afff6a3170e118Kirill Grouchnikov set.playSequentially(animators.toArray(new ObjectAnimator[0])); 135829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu set.setInterpolator(ANIM_INTERPOLATOR); 136829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu stateListAnimator.addState(ENABLED_STATE_SET, set); 137829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu 138829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu // Animate everything to 0 when disabled 139829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu set = new AnimatorSet(); 140829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu set.play(ObjectAnimator.ofFloat(mView, "elevation", 0f).setDuration(0)) 141829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu .with(ObjectAnimator.ofFloat(mView, View.TRANSLATION_Z, 0f).setDuration(0)); 142829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu set.setInterpolator(ANIM_INTERPOLATOR); 143829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu stateListAnimator.addState(EMPTY_STATE_SET, set); 144829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu 145829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu mView.setStateListAnimator(stateListAnimator); 146829c95c8a3fd508b798bedff028d7d6b55e16ce5Andrei Stingaceanu } 1476d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes 1486d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes if (mShadowViewDelegate.isCompatPaddingEnabled()) { 1496d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes updatePadding(); 1506d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes } 1516d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes } 1526d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes 1536d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes @Override 1546d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes public float getElevation() { 1556d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes return mView.getElevation(); 1566d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes } 1576d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes 1586d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes @Override 1596d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes void onCompatShadowChanged() { 1606d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes updatePadding(); 1616d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes } 1626d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes 1636d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes @Override 1646d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes void onPaddingUpdated(Rect padding) { 1656d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes if (mShadowViewDelegate.isCompatPaddingEnabled()) { 1666d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes mInsetDrawable = new InsetDrawable(mRippleDrawable, 1676d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes padding.left, padding.top, padding.right, padding.bottom); 1686d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes mShadowViewDelegate.setBackgroundDrawable(mInsetDrawable); 1696d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes } else { 1706d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes mShadowViewDelegate.setBackgroundDrawable(mRippleDrawable); 1716d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes } 1729840efe3dbdc7026521da8576574c55120782f6cChris Banes } 1739840efe3dbdc7026521da8576574c55120782f6cChris Banes 1749840efe3dbdc7026521da8576574c55120782f6cChris Banes @Override 1759840efe3dbdc7026521da8576574c55120782f6cChris Banes void onDrawableStateChanged(int[] state) { 1769840efe3dbdc7026521da8576574c55120782f6cChris Banes // no-op 1779840efe3dbdc7026521da8576574c55120782f6cChris Banes } 1789840efe3dbdc7026521da8576574c55120782f6cChris Banes 1799840efe3dbdc7026521da8576574c55120782f6cChris Banes @Override 1809840efe3dbdc7026521da8576574c55120782f6cChris Banes void jumpDrawableToCurrentState() { 1819840efe3dbdc7026521da8576574c55120782f6cChris Banes // no-op 1829840efe3dbdc7026521da8576574c55120782f6cChris Banes } 1839840efe3dbdc7026521da8576574c55120782f6cChris Banes 184d9770e12c8ff2d4417700492c6616572be897e93Chris Banes @Override 185d9770e12c8ff2d4417700492c6616572be897e93Chris Banes boolean requirePreDrawListener() { 186d9770e12c8ff2d4417700492c6616572be897e93Chris Banes return false; 187d9770e12c8ff2d4417700492c6616572be897e93Chris Banes } 188d9770e12c8ff2d4417700492c6616572be897e93Chris Banes 18980de0674c28a2bd9ade11f24a3b0e46ea83b6847Chris Banes @Override 19080de0674c28a2bd9ade11f24a3b0e46ea83b6847Chris Banes CircularBorderDrawable newCircularDrawable() { 19180de0674c28a2bd9ade11f24a3b0e46ea83b6847Chris Banes return new CircularBorderDrawableLollipop(); 19280de0674c28a2bd9ade11f24a3b0e46ea83b6847Chris Banes } 1936d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes 19415375aa6fd54b036f97f99229aefab2822c8a1c9Aurimas Liutikas @Override 1951c4d0c9dec028624cd661be53e68b1464b14ab7fChris Banes GradientDrawable newGradientDrawableForShape() { 1961c4d0c9dec028624cd661be53e68b1464b14ab7fChris Banes return new AlwaysStatefulGradientDrawable(); 1971c4d0c9dec028624cd661be53e68b1464b14ab7fChris Banes } 1981c4d0c9dec028624cd661be53e68b1464b14ab7fChris Banes 1991c4d0c9dec028624cd661be53e68b1464b14ab7fChris Banes @Override 2006d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes void getPadding(Rect rect) { 2016d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes if (mShadowViewDelegate.isCompatPaddingEnabled()) { 2026d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes final float radius = mShadowViewDelegate.getRadius(); 2036d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes final float maxShadowSize = getElevation() + mPressedTranslationZ; 2046d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes final int hPadding = (int) Math.ceil( 2056d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes ShadowDrawableWrapper.calculateHorizontalPadding(maxShadowSize, radius, false)); 2066d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes final int vPadding = (int) Math.ceil( 2076d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes ShadowDrawableWrapper.calculateVerticalPadding(maxShadowSize, radius, false)); 2086d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes rect.set(hPadding, vPadding, hPadding, vPadding); 2096d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes } else { 2106d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes rect.set(0, 0, 0, 0); 2116d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes } 2126d7a9a02765e4cb497081e66dafb5d9fa76f4312Chris Banes } 2131c4d0c9dec028624cd661be53e68b1464b14ab7fChris Banes 2141c4d0c9dec028624cd661be53e68b1464b14ab7fChris Banes /** 2151c4d0c9dec028624cd661be53e68b1464b14ab7fChris Banes * LayerDrawable on L+ caches its isStateful() state and doesn't refresh it, 2161c4d0c9dec028624cd661be53e68b1464b14ab7fChris Banes * meaning that if we apply a tint to one of its children, the parent doesn't become 2171c4d0c9dec028624cd661be53e68b1464b14ab7fChris Banes * stateful and the tint doesn't work for state changes. We workaround it by saying that we 2181c4d0c9dec028624cd661be53e68b1464b14ab7fChris Banes * are always stateful. If we don't have a stateful tint, the change is ignored anyway. 2191c4d0c9dec028624cd661be53e68b1464b14ab7fChris Banes */ 2201c4d0c9dec028624cd661be53e68b1464b14ab7fChris Banes static class AlwaysStatefulGradientDrawable extends GradientDrawable { 2211c4d0c9dec028624cd661be53e68b1464b14ab7fChris Banes @Override 2221c4d0c9dec028624cd661be53e68b1464b14ab7fChris Banes public boolean isStateful() { 2231c4d0c9dec028624cd661be53e68b1464b14ab7fChris Banes return true; 2241c4d0c9dec028624cd661be53e68b1464b14ab7fChris Banes } 2251c4d0c9dec028624cd661be53e68b1464b14ab7fChris Banes } 226124d52000d70f3a0ef64b1c70b72238441cbf0edDeepanshu Gupta} 227