ViewInvertHelper.java revision 4e857f4ef0357e05806819d0488a73a12208fe8f
10dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh/* 20dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * Copyright (C) 2014 The Android Open Source Project 30dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * 40dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * Licensed under the Apache License, Version 2.0 (the "License"); 50dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * you may not use this file except in compliance with the License. 60dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * You may obtain a copy of the License at 70dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * 80dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * http://www.apache.org/licenses/LICENSE-2.0 90dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * 100dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * Unless required by applicable law or agreed to in writing, software 110dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * distributed under the License is distributed on an "AS IS" BASIS, 120dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * See the License for the specific language governing permissions and 140dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * limitations under the License 150dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh */ 160dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 170dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehpackage com.android.systemui; 180dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 190dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehimport android.animation.Animator; 200dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehimport android.animation.AnimatorListenerAdapter; 210dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehimport android.animation.ValueAnimator; 220dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehimport android.graphics.ColorMatrix; 230dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehimport android.graphics.ColorMatrixColorFilter; 240dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehimport android.graphics.Paint; 250dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehimport android.view.View; 260dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehimport android.view.animation.AnimationUtils; 270dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehimport android.view.animation.Interpolator; 280dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 290dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehimport com.android.systemui.statusbar.phone.NotificationPanelView; 300dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 310dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh/** 320dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh * Helper to invert the colors of views and fade between the states. 330dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh */ 340dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yehpublic class ViewInvertHelper { 350dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 360dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh private final Paint mDarkPaint = new Paint(); 370dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh private final Interpolator mLinearOutSlowInInterpolator; 380dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh private final View mTarget; 390dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh private final ColorMatrix mMatrix = new ColorMatrix(); 400dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh private final ColorMatrix mGrayscaleMatrix = new ColorMatrix(); 410dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh private final long mFadeDuration; 420dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 430dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh public ViewInvertHelper(View target, long fadeDuration) { 440dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh mTarget = target; 450dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(mTarget.getContext(), 46ead9146f844ee194a4f4244ba8ae1a3aece12b63Yin-Chia Yeh android.R.interpolator.linear_out_slow_in); 470dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh mFadeDuration = fadeDuration; 480dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh } 490dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 500dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh public void fade(final boolean invert, long delay) { 510dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh float startIntensity = invert ? 0f : 1f; 520dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh float endIntensity = invert ? 1f : 0f; 530dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity); 540dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 550dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh @Override 560dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh public void onAnimationUpdate(ValueAnimator animation) { 570dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh updateInvertPaint((Float) animation.getAnimatedValue()); 580dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh mTarget.setLayerType(View.LAYER_TYPE_HARDWARE, mDarkPaint); 590dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh } 600dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh }); 610dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh animator.addListener(new AnimatorListenerAdapter() { 620dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh @Override 630dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh public void onAnimationEnd(Animator animation) { 640dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh if (!invert) { 650dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh mTarget.setLayerType(View.LAYER_TYPE_NONE, null); 660dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh } 670dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh } 680dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh }); 690dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh animator.setDuration(mFadeDuration); 70ead9146f844ee194a4f4244ba8ae1a3aece12b63Yin-Chia Yeh animator.setInterpolator(mLinearOutSlowInInterpolator); 71ead9146f844ee194a4f4244ba8ae1a3aece12b63Yin-Chia Yeh animator.setStartDelay(delay); 720dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh animator.start(); 730dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh } 740dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 750dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh public void update(boolean invert) { 760dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh if (invert) { 770dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh updateInvertPaint(1f); 780dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh mTarget.setLayerType(View.LAYER_TYPE_HARDWARE, mDarkPaint); 790dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh } else { 800dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh mTarget.setLayerType(View.LAYER_TYPE_NONE, null); 810dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh } 820dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh } 830dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 840dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh public View getTarget() { 850dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh return mTarget; 860dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh } 870dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 880dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh private void updateInvertPaint(float intensity) { 89ead9146f844ee194a4f4244ba8ae1a3aece12b63Yin-Chia Yeh float components = 1 - 2 * intensity; 90ead9146f844ee194a4f4244ba8ae1a3aece12b63Yin-Chia Yeh final float[] invert = { 910dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh components, 0f, 0f, 0f, 255f * intensity, 920dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 0f, components, 0f, 0f, 255f * intensity, 930dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 0f, 0f, components, 0f, 255f * intensity, 940dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh 0f, 0f, 0f, 1f, 0f 950dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh }; 960dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh mMatrix.set(invert); 970dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh mGrayscaleMatrix.setSaturation(1 - intensity); 980dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh mMatrix.preConcat(mGrayscaleMatrix); 990dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh mDarkPaint.setColorFilter(new ColorMatrixColorFilter(mMatrix)); 1000dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh } 1010dea57fd9fc4b2ccaab97d9477359fbd5a626f5cYin-Chia Yeh}