ScrimView.java revision 6811d728fb988a32cbfc836b768a261a7f60c98a
1a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek/*
2a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek * Copyright (C) 2014 The Android Open Source Project
3a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek *
4a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek * Licensed under the Apache License, Version 2.0 (the "License");
5a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek * you may not use this file except in compliance with the License.
6a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek * You may obtain a copy of the License at
7a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek *
8a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek *      http://www.apache.org/licenses/LICENSE-2.0
9a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek *
10a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek * Unless required by applicable law or agreed to in writing, software
11a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek * distributed under the License is distributed on an "AS IS" BASIS,
12a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek * See the License for the specific language governing permissions and
14a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek * limitations under the License
15a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek */
16a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek
17a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinekpackage com.android.systemui.statusbar;
18a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek
19a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinekimport android.animation.Animator;
20a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinekimport android.animation.AnimatorListenerAdapter;
21a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinekimport android.animation.ValueAnimator;
22a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinekimport android.content.Context;
23a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinekimport android.graphics.Canvas;
24a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinekimport android.graphics.Color;
256811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinekimport android.graphics.Paint;
26a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinekimport android.graphics.PorterDuff;
276811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinekimport android.graphics.PorterDuffXfermode;
286811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinekimport android.graphics.Rect;
29a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinekimport android.util.AttributeSet;
30a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinekimport android.view.View;
31a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinekimport android.view.animation.Interpolator;
32a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek
33a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek/**
34a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek * A view which can draw a scrim
35a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek */
36a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinekpublic class ScrimView extends View
37a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek{
386811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek    private final Paint mPaint = new Paint();
39a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    private int mScrimColor;
402bc5406d7aa78a24f907e45690525e6633a78f21Jorim Jaggi    private boolean mIsEmpty = true;
41a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    private boolean mDrawAsSrc;
42a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    private float mViewAlpha = 1.0f;
43a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    private ValueAnimator mAlphaAnimator;
446811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek    private Rect mExcludedRect = new Rect();
456811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek    private boolean mHasExcludedArea;
46a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    private ValueAnimator.AnimatorUpdateListener mAlphaUpdateListener
47a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek            = new ValueAnimator.AnimatorUpdateListener() {
48a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        @Override
49a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        public void onAnimationUpdate(ValueAnimator animation) {
50a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek            mViewAlpha = (float) animation.getAnimatedValue();
51a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek            invalidate();
52a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        }
53a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    };
54a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    private AnimatorListenerAdapter mClearAnimatorListener = new AnimatorListenerAdapter() {
55a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        @Override
56a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        public void onAnimationEnd(Animator animation) {
57a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek            mAlphaAnimator = null;
58a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        }
59a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    };
60a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek
61a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    public ScrimView(Context context) {
62a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        this(context, null);
63a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    }
64a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek
65a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    public ScrimView(Context context, AttributeSet attrs) {
66a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        this(context, attrs, 0);
67a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    }
68a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek
69a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    public ScrimView(Context context, AttributeSet attrs, int defStyleAttr) {
70a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        this(context, attrs, defStyleAttr, 0);
71a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    }
72a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek
73a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    public ScrimView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
74a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        super(context, attrs, defStyleAttr, defStyleRes);
75a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    }
76a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek
77a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    @Override
78a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    protected void onDraw(Canvas canvas) {
790e66439387e36876de94a60658917a7f3b0e6d27Jorim Jaggi        if (mDrawAsSrc || (!mIsEmpty && mViewAlpha > 0f)) {
80a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek            PorterDuff.Mode mode = mDrawAsSrc ? PorterDuff.Mode.SRC : PorterDuff.Mode.SRC_OVER;
81a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek            int color = mScrimColor;
82a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek            color = Color.argb((int) (Color.alpha(color) * mViewAlpha), Color.red(color),
83a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek                    Color.green(color), Color.blue(color));
846811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek            if (!mHasExcludedArea) {
856811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek                canvas.drawColor(color, mode);
866811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek            } else {
876811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek                mPaint.setColor(color);
886811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek                if (mExcludedRect.top > 0) {
896811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek                    canvas.drawRect(0, 0, getWidth(), mExcludedRect.top, mPaint);
906811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek                }
916811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek                if (mExcludedRect.left > 0) {
926811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek                    canvas.drawRect(0,  mExcludedRect.top, mExcludedRect.left, mExcludedRect.bottom,
936811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek                            mPaint);
946811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek                }
956811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek                if (mExcludedRect.right < getWidth()) {
966811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek                    canvas.drawRect(mExcludedRect.right,
976811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek                            mExcludedRect.top,
986811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek                            getWidth(),
996811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek                            mExcludedRect.bottom,
1006811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek                            mPaint);
1016811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek                }
1026811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek                if (mExcludedRect.bottom < getHeight()) {
1036811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek                    canvas.drawRect(0,  mExcludedRect.bottom, getWidth(), getHeight(), mPaint);
1046811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek                }
1056811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek            }
106a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        }
107a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    }
108a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek
109a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    public void setDrawAsSrc(boolean asSrc) {
110a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        mDrawAsSrc = asSrc;
1116811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek        mPaint.setXfermode(new PorterDuffXfermode(mDrawAsSrc ? PorterDuff.Mode.SRC
1126811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek                : PorterDuff.Mode.SRC_OVER));
113a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        invalidate();
114a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    }
115a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek
116a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    public void setScrimColor(int color) {
117a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        if (color != mScrimColor) {
118a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek            mIsEmpty = Color.alpha(color) == 0;
119a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek            mScrimColor = color;
120a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek            invalidate();
121a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        }
122a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    }
123a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek
124a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    public int getScrimColor() {
125a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        return mScrimColor;
126a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    }
127a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek
128a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    @Override
129a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    public boolean hasOverlappingRendering() {
130a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        return false;
131a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    }
132a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek
133a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    public void setViewAlpha(float alpha) {
134a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        if (mAlphaAnimator != null) {
135a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek            mAlphaAnimator.cancel();
136a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        }
137a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        mViewAlpha = alpha;
138a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        invalidate();
139a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    }
140a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek
141a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    public void animateViewAlpha(float alpha, long durationOut, Interpolator interpolator) {
142a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        if (mAlphaAnimator != null) {
143a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek            mAlphaAnimator.cancel();
144a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        }
145a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        mAlphaAnimator = ValueAnimator.ofFloat(mViewAlpha, alpha);
146a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        mAlphaAnimator.addUpdateListener(mAlphaUpdateListener);
147a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        mAlphaAnimator.addListener(mClearAnimatorListener);
148a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        mAlphaAnimator.setInterpolator(interpolator);
149a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        mAlphaAnimator.setDuration(durationOut);
150a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek        mAlphaAnimator.start();
151a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek    }
1526811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek
1536811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek    public void setExcludedArea(Rect area) {
1546811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek        if (area == null) {
1556811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek            mHasExcludedArea = false;
1566811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek            invalidate();
1576811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek            return;
1586811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek        }
1596811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek        area.left = Math.max(area.left, 0);
1606811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek        area.top = Math.max(area.top, 0);
1616811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek        area.right = Math.min(area.right, getWidth());
1626811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek        area.bottom = Math.min(area.bottom, getHeight());
1636811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek        mExcludedRect.set(area);
1646811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek        mHasExcludedArea = area.left < area.right && area.top < area.bottom;
1656811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek        invalidate();
1666811d728fb988a32cbfc836b768a261a7f60c98aSelim Cinek    }
167a0fad3ba06d0352f640532e69ed3d540b3795535Selim Cinek}
168