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