AnimateableViewBounds.java revision ebfc6981828b0699eef85c58b23a61f2cac41af3
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 com.android.systemui.recents.views; 18 19import android.animation.ObjectAnimator; 20import android.animation.ValueAnimator; 21import android.graphics.Outline; 22import android.graphics.Rect; 23import android.view.View; 24import android.view.ViewOutlineProvider; 25import com.android.systemui.recents.RecentsConfiguration; 26 27/* An outline provider that has a clip and outline that can be animated. */ 28public class AnimateableViewBounds extends ViewOutlineProvider { 29 30 RecentsConfiguration mConfig; 31 32 View mSourceView; 33 Rect mClipRect = new Rect(); 34 Rect mOutlineClipRect = new Rect(); 35 int mCornerRadius; 36 float mAlpha = 1f; 37 final float mMinAlpha = 0.25f; 38 39 ObjectAnimator mClipTopAnimator; 40 ObjectAnimator mClipRightAnimator; 41 ObjectAnimator mClipBottomAnimator; 42 43 public AnimateableViewBounds(View source, int cornerRadius) { 44 mConfig = RecentsConfiguration.getInstance(); 45 mSourceView = source; 46 mCornerRadius = cornerRadius; 47 mSourceView.setClipToOutline(true); 48 setClipTop(getClipTop()); 49 setClipRight(getClipRight()); 50 setClipBottom(getClipBottom()); 51 setOutlineClipBottom(getOutlineClipBottom()); 52 } 53 54 @Override 55 public void getOutline(View view, Outline outline) { 56 outline.setAlpha(mMinAlpha + mAlpha / (1f - mMinAlpha)); 57 outline.setRoundRect(Math.max(mClipRect.left, mOutlineClipRect.left), 58 Math.max(mClipRect.top, mOutlineClipRect.top), 59 mSourceView.getMeasuredWidth() - Math.max(mClipRect.right, mOutlineClipRect.right), 60 mSourceView.getMeasuredHeight() - Math.max(mClipRect.bottom, mOutlineClipRect.bottom), 61 mCornerRadius); 62 } 63 64 /** Sets the view outline alpha. */ 65 void setAlpha(float alpha) { 66 if (Float.compare(alpha, mAlpha) != 0) { 67 mAlpha = alpha; 68 mSourceView.invalidateOutline(); 69 } 70 } 71 72 /** Animates the top clip. */ 73 void animateClipTop(int top, int duration, ValueAnimator.AnimatorUpdateListener updateListener) { 74 if (mClipTopAnimator != null) { 75 mClipTopAnimator.removeAllListeners(); 76 mClipTopAnimator.cancel(); 77 } 78 mClipTopAnimator = ObjectAnimator.ofInt(this, "clipTop", top); 79 mClipTopAnimator.setDuration(duration); 80 mClipTopAnimator.setInterpolator(mConfig.fastOutSlowInInterpolator); 81 if (updateListener != null) { 82 mClipTopAnimator.addUpdateListener(updateListener); 83 } 84 mClipTopAnimator.start(); 85 } 86 87 /** Sets the top clip. */ 88 public void setClipTop(int top) { 89 if (top != mClipRect.top) { 90 mClipRect.top = top; 91 mSourceView.invalidateOutline(); 92 } 93 } 94 95 /** Returns the top clip. */ 96 public int getClipTop() { 97 return mClipRect.top; 98 } 99 100 /** Animates the right clip. */ 101 void animateClipRight(int right, int duration) { 102 if (mClipRightAnimator != null) { 103 mClipRightAnimator.removeAllListeners(); 104 mClipRightAnimator.cancel(); 105 } 106 mClipRightAnimator = ObjectAnimator.ofInt(this, "clipRight", right); 107 mClipRightAnimator.setDuration(duration); 108 mClipRightAnimator.setInterpolator(mConfig.fastOutSlowInInterpolator); 109 mClipRightAnimator.start(); 110 } 111 112 /** Sets the right clip. */ 113 public void setClipRight(int right) { 114 if (right != mClipRect.right) { 115 mClipRect.right = right; 116 mSourceView.invalidateOutline(); 117 } 118 } 119 120 /** Returns the right clip. */ 121 public int getClipRight() { 122 return mClipRect.right; 123 } 124 125 /** Animates the bottom clip. */ 126 void animateClipBottom(int bottom, int duration) { 127 if (mClipBottomAnimator != null) { 128 mClipBottomAnimator.removeAllListeners(); 129 mClipBottomAnimator.cancel(); 130 } 131 mClipBottomAnimator = ObjectAnimator.ofInt(this, "clipBottom", bottom); 132 mClipBottomAnimator.setDuration(duration); 133 mClipBottomAnimator.setInterpolator(mConfig.fastOutSlowInInterpolator); 134 mClipBottomAnimator.start(); 135 } 136 137 /** Sets the bottom clip. */ 138 public void setClipBottom(int bottom) { 139 if (bottom != mClipRect.bottom) { 140 mClipRect.bottom = bottom; 141 mSourceView.invalidateOutline(); 142 } 143 } 144 145 /** Returns the bottom clip. */ 146 public int getClipBottom() { 147 return mClipRect.bottom; 148 } 149 150 /** Sets the outline bottom clip. */ 151 public void setOutlineClipBottom(int bottom) { 152 if (bottom != mOutlineClipRect.bottom) { 153 mOutlineClipRect.bottom = bottom; 154 mSourceView.invalidateOutline(); 155 } 156 } 157 158 /** Gets the outline bottom clip. */ 159 public int getOutlineClipBottom() { 160 return mOutlineClipRect.bottom; 161 } 162} 163