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}