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