TaskView.java revision 0d767551c55d9e594a0b944bd1926c21a344b5ae
1/* 2 * Copyright (C) 2014 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.recents.views; 18 19import android.animation.Animator; 20import android.animation.AnimatorSet; 21import android.animation.ObjectAnimator; 22import android.content.Context; 23import android.graphics.Canvas; 24import android.graphics.Outline; 25import android.graphics.Path; 26import android.graphics.Rect; 27import android.graphics.RectF; 28import android.util.AttributeSet; 29import android.view.View; 30import android.widget.FrameLayout; 31import com.android.systemui.R; 32import com.android.systemui.recents.BakedBezierInterpolator; 33import com.android.systemui.recents.Constants; 34import com.android.systemui.recents.RecentsConfiguration; 35import com.android.systemui.recents.Utilities; 36import com.android.systemui.recents.model.Task; 37 38 39/* A task view */ 40public class TaskView extends FrameLayout implements View.OnClickListener, Task.TaskCallbacks { 41 /** The TaskView callbacks */ 42 interface TaskViewCallbacks { 43 public void onTaskIconClicked(TaskView tv); 44 // public void onTaskViewReboundToTask(TaskView tv, Task t); 45 } 46 47 Task mTask; 48 boolean mTaskDataLoaded; 49 50 TaskThumbnailView mThumbnailView; 51 TaskBarView mBarView; 52 TaskViewCallbacks mCb; 53 54 55 public TaskView(Context context) { 56 this(context, null); 57 } 58 59 public TaskView(Context context, AttributeSet attrs) { 60 this(context, attrs, 0); 61 } 62 63 public TaskView(Context context, AttributeSet attrs, int defStyleAttr) { 64 this(context, attrs, defStyleAttr, 0); 65 } 66 67 public TaskView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 68 super(context, attrs, defStyleAttr, defStyleRes); 69 } 70 71 @Override 72 protected void onFinishInflate() { 73 // Bind the views 74 mThumbnailView = (TaskThumbnailView) findViewById(R.id.task_view_thumbnail); 75 mBarView = (TaskBarView) findViewById(R.id.task_view_bar); 76 mBarView.mApplicationIcon.setOnClickListener(this); 77 if (mTaskDataLoaded) { 78 onTaskDataLoaded(false); 79 } 80 } 81 82 /** Set callback */ 83 void setCallbacks(TaskViewCallbacks cb) { 84 mCb = cb; 85 } 86 87 /** Gets the task */ 88 Task getTask() { 89 return mTask; 90 } 91 92 /** Synchronizes this view's properties with the task's transform */ 93 void updateViewPropertiesToTaskTransform(TaskViewTransform animateFromTransform, 94 TaskViewTransform toTransform, int duration) { 95 if (duration > 0) { 96 if (animateFromTransform != null) { 97 setTranslationY(animateFromTransform.translationY); 98 setScaleX(animateFromTransform.scale); 99 setScaleY(animateFromTransform.scale); 100 setAlpha(animateFromTransform.alpha); 101 } 102 animate().translationY(toTransform.translationY) 103 .scaleX(toTransform.scale) 104 .scaleY(toTransform.scale) 105 .alpha(toTransform.alpha) 106 .setDuration(duration) 107 .setInterpolator(BakedBezierInterpolator.INSTANCE) 108 .withLayer() 109 .start(); 110 } else { 111 setTranslationY(toTransform.translationY); 112 setScaleX(toTransform.scale); 113 setScaleY(toTransform.scale); 114 setAlpha(toTransform.alpha); 115 } 116 } 117 118 /** Returns an animator to animate this task to the specified transform */ 119 Animator getAnimatorToTaskTransform(TaskViewTransform toTransform) { 120 AnimatorSet anims = new AnimatorSet(); 121 anims.playTogether( 122 ObjectAnimator.ofFloat(this, "translationY", toTransform.translationY), 123 ObjectAnimator.ofFloat(this, "scaleX", toTransform.scale), 124 ObjectAnimator.ofFloat(this, "scaleY", toTransform.scale), 125 ObjectAnimator.ofFloat(this, "alpha", toTransform.alpha) 126 ); 127 return anims; 128 } 129 130 /** Resets this view's properties */ 131 void resetViewProperties() { 132 setTranslationX(0f); 133 setTranslationY(0f); 134 setScaleX(1f); 135 setScaleY(1f); 136 setAlpha(1f); 137 } 138 139 void prepareTaskTransformForFilterTaskHidden(TaskViewTransform toTransform) { 140 // Fade the view out and slide it away 141 toTransform.alpha = 0f; 142 toTransform.translationY += 200; 143 } 144 145 void prepareTaskTransformForFilterTaskVisible(TaskViewTransform fromTransform) { 146 // Fade the view in 147 fromTransform.alpha = 0f; 148 } 149 150 /** Animates this task view as it enters recents */ 151 public void animateOnEnterRecents() { 152 RecentsConfiguration config = RecentsConfiguration.getInstance(); 153 int translate = config.pxFromDp(10); 154 mBarView.setScaleX(1.25f); 155 mBarView.setScaleY(1.25f); 156 mBarView.setAlpha(0f); 157 mBarView.setTranslationX(translate / 2); 158 mBarView.setTranslationY(-translate); 159 mBarView.animate() 160 .alpha(1f) 161 .scaleX(1f) 162 .scaleY(1f) 163 .translationX(0) 164 .translationY(0) 165 .setStartDelay(235) 166 .setInterpolator(BakedBezierInterpolator.INSTANCE) 167 .setDuration(config.taskBarEnterAnimDuration) 168 .withLayer() 169 .start(); 170 } 171 172 /** Animates this task view as it exits recents */ 173 public void animateOnLeavingRecents(final Runnable r) { 174 RecentsConfiguration config = RecentsConfiguration.getInstance(); 175 int translate = config.pxFromDp(10); 176 mBarView.animate() 177 .alpha(0f) 178 .scaleX(1.1f) 179 .scaleY(1.1f) 180 .translationX(translate / 2) 181 .translationY(-translate) 182 .setStartDelay(0) 183 .setInterpolator(BakedBezierInterpolator.INSTANCE) 184 .setDuration(Utilities.calculateTranslationAnimationDuration(translate)) 185 .withLayer() 186 .withEndAction(new Runnable() { 187 @Override 188 public void run() { 189 post(r); 190 } 191 }) 192 .start(); 193 } 194 195 /** Returns the rect we want to clip (it may not be the full rect) */ 196 Rect getClippingRect(Rect outRect) { 197 getHitRect(outRect); 198 // XXX: We should get the hit rect of the thumbnail view and intersect, but this is faster 199 outRect.right = outRect.left + mThumbnailView.getRight(); 200 outRect.bottom = outRect.top + mThumbnailView.getBottom(); 201 return outRect; 202 } 203 204 /** Enable the hw layers on this task view */ 205 void enableHwLayers() { 206 mThumbnailView.setLayerType(View.LAYER_TYPE_HARDWARE, null); 207 } 208 209 /** Disable the hw layers on this task view */ 210 void disableHwLayers() { 211 mThumbnailView.setLayerType(View.LAYER_TYPE_NONE, null); 212 } 213 214 /**** TaskCallbacks Implementation ****/ 215 216 /** Binds this task view to the task */ 217 public void onTaskBound(Task t) { 218 mTask = t; 219 mTask.setCallbacks(this); 220 } 221 222 @Override 223 public void onTaskDataLoaded(boolean reloadingTaskData) { 224 if (mThumbnailView != null && mBarView != null) { 225 // Bind each of the views to the new task data 226 mThumbnailView.rebindToTask(mTask, reloadingTaskData); 227 mBarView.rebindToTask(mTask, reloadingTaskData); 228 } 229 mTaskDataLoaded = true; 230 } 231 232 @Override 233 public void onTaskDataUnloaded() { 234 if (mThumbnailView != null && mBarView != null) { 235 // Unbind each of the views from the task data and remove the task callback 236 mTask.setCallbacks(null); 237 mThumbnailView.unbindFromTask(); 238 mBarView.unbindFromTask(); 239 } 240 mTaskDataLoaded = false; 241 } 242 243 @Override 244 public void onClick(View v) { 245 mCb.onTaskIconClicked(this); 246 } 247}