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