1/* 2 * Copyright (C) 2016 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.statusbar.notification; 18 19import android.graphics.drawable.Icon; 20import android.util.Pools; 21import android.view.View; 22import android.widget.ImageView; 23 24import com.android.systemui.Interpolators; 25import com.android.systemui.R; 26import com.android.systemui.statusbar.CrossFadeHelper; 27import com.android.systemui.statusbar.TransformableView; 28import com.android.systemui.statusbar.stack.StackStateAnimator; 29 30/** 31 * A transform state of a image view. 32*/ 33public class ImageTransformState extends TransformState { 34 public static final long ANIMATION_DURATION_LENGTH = 210; 35 36 public static final int ICON_TAG = R.id.image_icon_tag; 37 private static Pools.SimplePool<ImageTransformState> sInstancePool 38 = new Pools.SimplePool<>(40); 39 private Icon mIcon; 40 41 @Override 42 public void initFrom(View view) { 43 super.initFrom(view); 44 if (view instanceof ImageView) { 45 mIcon = (Icon) view.getTag(ICON_TAG); 46 } 47 } 48 49 @Override 50 protected boolean sameAs(TransformState otherState) { 51 if (otherState instanceof ImageTransformState) { 52 return mIcon != null && mIcon.sameAs(((ImageTransformState) otherState).getIcon()); 53 } 54 return super.sameAs(otherState); 55 } 56 57 @Override 58 public void appear(float transformationAmount, TransformableView otherView) { 59 if (otherView instanceof HybridNotificationView) { 60 if (transformationAmount == 0.0f) { 61 mTransformedView.setPivotY(0); 62 mTransformedView.setPivotX(mTransformedView.getWidth() / 2); 63 prepareFadeIn(); 64 } 65 transformationAmount = mapToDuration(transformationAmount); 66 CrossFadeHelper.fadeIn(mTransformedView, transformationAmount, false /* remap */); 67 transformationAmount = Interpolators.LINEAR_OUT_SLOW_IN.getInterpolation( 68 transformationAmount); 69 mTransformedView.setScaleX(transformationAmount); 70 mTransformedView.setScaleY(transformationAmount); 71 } else { 72 super.appear(transformationAmount, otherView); 73 } 74 } 75 76 @Override 77 public void disappear(float transformationAmount, TransformableView otherView) { 78 if (otherView instanceof HybridNotificationView) { 79 if (transformationAmount == 0.0f) { 80 mTransformedView.setPivotY(0); 81 mTransformedView.setPivotX(mTransformedView.getWidth() / 2); 82 } 83 transformationAmount = mapToDuration(1.0f - transformationAmount); 84 CrossFadeHelper.fadeOut(mTransformedView, 1.0f - transformationAmount, 85 false /* remap */); 86 transformationAmount = Interpolators.LINEAR_OUT_SLOW_IN.getInterpolation( 87 transformationAmount); 88 mTransformedView.setScaleX(transformationAmount); 89 mTransformedView.setScaleY(transformationAmount); 90 } else { 91 super.disappear(transformationAmount, otherView); 92 } 93 } 94 95 private static float mapToDuration(float scaleAmount) { 96 // Assuming a linear interpolator, we can easily map it to our new duration 97 scaleAmount = (scaleAmount * StackStateAnimator.ANIMATION_DURATION_STANDARD 98 - (StackStateAnimator.ANIMATION_DURATION_STANDARD - ANIMATION_DURATION_LENGTH)) 99 / ANIMATION_DURATION_LENGTH; 100 return Math.max(Math.min(scaleAmount, 1.0f), 0.0f); 101 } 102 103 public Icon getIcon() { 104 return mIcon; 105 } 106 107 public static ImageTransformState obtain() { 108 ImageTransformState instance = sInstancePool.acquire(); 109 if (instance != null) { 110 return instance; 111 } 112 return new ImageTransformState(); 113 } 114 115 @Override 116 protected boolean transformScale() { 117 return true; 118 } 119 120 @Override 121 public void recycle() { 122 super.recycle(); 123 sInstancePool.release(this); 124 } 125 126 @Override 127 protected void reset() { 128 super.reset(); 129 mIcon = null; 130 } 131} 132