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