Moving task view layout into resource.

- Using new activity icon/labels

Change-Id: If27bf60d2df75813213e9f3095baeb03085da8f7
This commit is contained in:
Winson Chung
2014-03-24 14:53:07 -07:00
parent 1d22bd1986
commit 37c8d8ef85
9 changed files with 315 additions and 258 deletions

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<com.android.systemui.recents.views.TaskView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.android.systemui.recents.views.TaskThumbnailView
android:id="@+id/task_view_thumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.android.systemui.recents.views.TaskBarView
android:id="@+id/task_view_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top|center_horizontal"
android:background="#88000000">
<ImageView
android:id="@+id/activity_icon"
android:layout_width="@dimen/recents_task_view_icon_size"
android:layout_height="@dimen/recents_task_view_icon_size"
android:layout_gravity="top|left"
android:padding="8dp" />
<TextView
android:id="@+id/activity_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|left"
android:layout_marginLeft="@dimen/recents_task_view_icon_size"
android:textSize="24sp"
android:textColor="#ffffffff"
android:text="@string/recents_empty_message"
android:fontFamily="sans-serif-thin" />
</com.android.systemui.recents.views.TaskBarView>
</com.android.systemui.recents.views.TaskView>

View File

@ -229,4 +229,7 @@
<!-- Default distance from each snap target that GlowPadView considers a "hit" -->
<dimen name="glowpadview_inner_radius">15dip</dimen>
<!-- The size of the icon in the recents task view. -->
<dimen name="recents_task_view_icon_size">60dp</dimen>
</resources>

View File

@ -50,7 +50,6 @@ public class Constants {
public static final boolean ClickEvents = false;
public static final boolean TouchEvents = false;
public static final boolean MeasureAndLayout = false;
public static final boolean Clipping = false;
public static final boolean HwLayers = false;
}
@ -107,14 +106,9 @@ public class Constants {
public static final boolean AnimateFrontTaskIconOnEnterRecents = true;
public static final boolean AnimateFrontTaskIconOnLeavingRecents = true;
public static final boolean AnimateFrontTaskIconOnEnterUseClip = false;
public static final boolean AnimateFrontTaskIconOnLeavingUseClip = false;
public static final boolean DrawColoredTaskBars = false;
public static final boolean UseRoundedCorners = true;
public static final float RoundedCornerRadiusDps = 3;
public static final float TaskBarHeightDps = 54;
public static final float TaskIconSizeDps = 60;
}
}
}

View File

@ -21,6 +21,7 @@ import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
@ -360,6 +361,7 @@ public class RecentsTaskLoader {
/** Reload the set of recent tasks */
SpaceNode reload(Context context, int preloadCount) {
Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|reload]");
Resources res = context.getResources();
ArrayList<Task> tasksToForceLoad = new ArrayList<Task>();
TaskStack stack = new TaskStack(context);
SpaceNode root = new SpaceNode(context);
@ -415,31 +417,38 @@ public class RecentsTaskLoader {
"[RecentsTaskLoader|preloadTask]",
"i: " + i + " task: " + t.baseIntent.getComponent().getPackageName());
Task task = new Task(t.persistentId, t.baseIntent, title);
String label = (t.activityLabel == null ? title : t.activityLabel.toString());
BitmapDrawable bd = null;
if (t.activityIcon != null) {
bd = new BitmapDrawable(res, t.activityIcon);
}
Task task = new Task(t.persistentId, t.baseIntent, label, bd);
// Load the icon (if possible and not the foremost task, from the cache)
if (!isForemostTask) {
task.icon = mIconCache.get(task.key);
if (task.icon != null) {
// Even though we get things from the cache, we should update them if
// they've changed in the bg
tasksToForceLoad.add(task);
if (task.icon != null) {
mIconCache.put(task.key, task.icon);
} else {
if (!isForemostTask) {
task.icon = mIconCache.get(task.key);
if (task.icon != null) {
// Even though we get things from the cache, we should update them
// if they've changed in the bg
tasksToForceLoad.add(task);
}
}
}
if (task.icon == null) {
task.icon = info.loadIcon(pm);
if (task.icon != null) {
mIconCache.put(task.key, task.icon);
} else {
task.icon = mDefaultIcon;
if (task.icon == null) {
task.icon = info.loadIcon(pm);
if (task.icon != null) {
mIconCache.put(task.key, task.icon);
} else {
task.icon = mDefaultIcon;
}
}
}
// Load the thumbnail (if possible and not the foremost task, from the cache)
if (!isForemostTask) {
task.thumbnail = mThumbnailCache.get(task.key);
if (task.thumbnail != null) {
// Even though we get things from the cache, we should update them if
// they've changed in the bg
@ -468,7 +477,7 @@ public class RecentsTaskLoader {
for (int j = 0; j < Constants.Values.RecentsTaskLoader.TaskEntryMultiplier; j++) {
Console.log(Constants.DebugFlags.App.TaskDataLoader,
" [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName());
stack.addTask(new Task(t.persistentId, t.baseIntent, title));
stack.addTask(new Task(t.persistentId, t.baseIntent, title, null, null));
}
}
}

View File

@ -67,8 +67,8 @@ public class Task {
TaskCallbacks mCb;
public Task(int id, Intent intent, String activityTitle) {
this(id, intent, activityTitle, null, null);
public Task(int id, Intent intent, String activityTitle, Drawable icon) {
this(id, intent, activityTitle, icon, null);
}
public Task(int id, Intent intent, String activityTitle, Drawable icon, Bitmap thumbnail) {

View File

@ -0,0 +1,86 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.recents.views;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.systemui.R;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.model.Task;
/* The task bar view */
class TaskBarView extends FrameLayout {
Task mTask;
ImageView mActivityIcon;
TextView mActivityDescription;
public TaskBarView(Context context) {
this(context, null);
}
public TaskBarView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TaskBarView(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public TaskBarView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onFinishInflate() {
// Initialize the icon and description views
mActivityIcon = (ImageView) findViewById(R.id.activity_icon);
mActivityDescription = (TextView) findViewById(R.id.activity_description);
}
/** Binds the bar view to the task */
void rebindToTask(Task t, boolean animate) {
mTask = t;
if (t.icon != null) {
mActivityIcon.setImageDrawable(t.icon);
mActivityDescription.setText(t.title);
if (animate) {
// XXX: Investigate how expensive it will be to create a second bitmap and crossfade
}
}
}
/** Unbinds the bar view from the task */
void unbindFromTask() {
mTask = null;
mActivityIcon.setImageDrawable(null);
mActivityDescription.setText("");
}
}

View File

@ -26,6 +26,7 @@ import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.Region;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
@ -40,6 +41,7 @@ import com.android.systemui.recents.RecentsTaskLoader;
import com.android.systemui.recents.Utilities;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.R;
import java.util.ArrayList;
@ -77,6 +79,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
int mStackViewsAnimationDuration;
boolean mStackViewsDirty = true;
boolean mAwaitingFirstLayout = true;
LayoutInflater mInflater;
public TaskStackView(Context context, TaskStack stack) {
super(context);
@ -85,6 +88,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
mScroller = new OverScroller(context);
mTouchHandler = new TaskStackViewTouchHandler(context, this);
mViewPool = new ViewPool<TaskView, Task>(context, this);
mInflater = LayoutInflater.from(context);
}
/** Sets the callbacks */
@ -580,7 +584,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
@Override
public TaskView createView(Context context) {
Console.log(Constants.DebugFlags.ViewPool.PoolCallbacks, "[TaskStackView|createPoolView]");
return new TaskView(context);
return (TaskView) mInflater.inflate(R.layout.recents_task_view, this, false);
}
@Override

View File

@ -0,0 +1,62 @@
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.recents.views;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ImageView;
import com.android.systemui.recents.model.Task;
/** The task thumbnail view */
public class TaskThumbnailView extends ImageView {
Task mTask;
public TaskThumbnailView(Context context) {
this(context, null);
}
public TaskThumbnailView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public TaskThumbnailView(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public TaskThumbnailView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
setScaleType(ScaleType.FIT_XY);
}
/** Binds the thumbnail view to the task */
void rebindToTask(Task t, boolean animate) {
mTask = t;
if (t.thumbnail != null) {
setImageBitmap(t.thumbnail);
if (animate) {
// XXX: Investigate how expensive it will be to create a second bitmap and crossfade
}
}
}
/** Unbinds the thumbnail view from the task */
void unbindFromTask() {
mTask = null;
setImageDrawable(null);
}
}

View File

@ -16,66 +16,67 @@
package com.android.systemui.recents.views;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.view.Gravity;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.android.systemui.recents.Console;
import com.android.systemui.R;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.model.Task;
/** The task thumbnail view */
class TaskThumbnailView extends ImageView {
/* A task view */
public class TaskView extends FrameLayout implements View.OnClickListener, Task.TaskCallbacks {
/** The TaskView callbacks */
interface TaskViewCallbacks {
public void onTaskIconClicked(TaskView tv);
// public void onTaskViewReboundToTask(TaskView tv, Task t);
}
Task mTask;
int mBarColor;
boolean mTaskDataLoaded;
TaskThumbnailView mThumbnailView;
TaskBarView mBarView;
TaskViewCallbacks mCb;
Path mRoundedRectClipPath = new Path();
public TaskThumbnailView(Context context) {
super(context);
setScaleType(ScaleType.FIT_XY);
public TaskView(Context context) {
this(context, null);
}
/** Binds the thumbnail view to the task */
void rebindToTask(Task t, boolean animate) {
mTask = t;
if (t.thumbnail != null) {
// Update the bar color
if (Constants.Values.TaskView.DrawColoredTaskBars) {
int[] colors = {0xFFCC0C39, 0xFFE6781E, 0xFFC8CF02, 0xFF1693A7};
mBarColor = colors[mTask.key.intent.getComponent().getPackageName().length() % colors.length];
}
public TaskView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
setImageBitmap(t.thumbnail);
if (animate) {
// XXX: Investigate how expensive it will be to create a second bitmap and crossfade
}
public TaskView(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public TaskView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
setWillNotDraw(false);
}
@Override
protected void onFinishInflate() {
// Bind the views
mThumbnailView = (TaskThumbnailView) findViewById(R.id.task_view_thumbnail);
mBarView = (TaskBarView) findViewById(R.id.task_view_bar);
if (mTaskDataLoaded) {
onTaskDataLoaded(false);
}
}
/** Unbinds the thumbnail view from the task */
void unbindFromTask() {
mTask = null;
setImageDrawable(null);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@ -95,150 +96,6 @@ class TaskThumbnailView extends ImageView {
}
super.onDraw(canvas);
if (Constants.Values.TaskView.DrawColoredTaskBars) {
RecentsConfiguration config = RecentsConfiguration.getInstance();
int taskBarHeight = config.pxFromDp(Constants.Values.TaskView.TaskBarHeightDps);
// XXX: If we actually use this, this should be pulled out into a TextView that we
// inflate
// Draw the task bar
Rect r = new Rect();
Paint p = new Paint();
p.setAntiAlias(true);
p.setSubpixelText(true);
p.setColor(mBarColor);
p.setTypeface(Typeface.create("sans-serif-light", Typeface.NORMAL));
canvas.drawRect(0, 0, getMeasuredWidth(), taskBarHeight, p);
p.setColor(0xFFffffff);
p.setTextSize(68);
p.getTextBounds("X", 0, 1, r);
int offset = (int) (taskBarHeight - r.height()) / 2;
canvas.drawText(mTask.title, offset, offset + r.height(), p);
}
}
}
/* The task icon view */
class TaskIconView extends ImageView {
Task mTask;
Path mClipPath = new Path();
float mClipRadius;
Point mClipOrigin = new Point();
ObjectAnimator mCircularClipAnimator;
public TaskIconView(Context context) {
super(context);
mClipPath = new Path();
mClipRadius = 1f;
}
/** Binds the icon view to the task */
void rebindToTask(Task t, boolean animate) {
mTask = t;
if (t.icon != null) {
setImageDrawable(t.icon);
if (animate) {
// XXX: Investigate how expensive it will be to create a second bitmap and crossfade
}
}
}
/** Unbinds the icon view from the task */
void unbindFromTask() {
mTask = null;
setImageDrawable(null);
}
/** Sets the circular clip radius on the icon */
public void setCircularClipRadius(float r) {
Console.log(Constants.DebugFlags.UI.Clipping, "[TaskView|setCircularClip]", "" + r);
mClipRadius = r;
invalidate();
}
/** Gets the circular clip radius on the icon */
public float getCircularClipRadius() {
return mClipRadius;
}
/** Animates the circular clip radius on the icon */
void animateCircularClip(boolean brNotTl, float newRadius, int duration, int startDelay,
TimeInterpolator interpolator,
AnimatorListenerAdapter listener) {
if (mCircularClipAnimator != null) {
mCircularClipAnimator.cancel();
mCircularClipAnimator.removeAllListeners();
}
if (brNotTl) {
mClipOrigin.set(0, 0);
} else {
mClipOrigin.set(getMeasuredWidth(), getMeasuredHeight());
}
mCircularClipAnimator = ObjectAnimator.ofFloat(this, "circularClipRadius", newRadius);
mCircularClipAnimator.setStartDelay(startDelay);
mCircularClipAnimator.setDuration(duration);
mCircularClipAnimator.setInterpolator(interpolator);
if (listener != null) {
mCircularClipAnimator.addListener(listener);
}
mCircularClipAnimator.start();
}
@Override
protected void onDraw(Canvas canvas) {
int saveCount = canvas.save(Canvas.CLIP_SAVE_FLAG);
int width = getMeasuredWidth();
int height = getMeasuredHeight();
int maxSize = (int) Math.ceil(Math.sqrt(width * width + height * height));
mClipPath.reset();
mClipPath.addCircle(mClipOrigin.x, mClipOrigin.y, mClipRadius * maxSize, Path.Direction.CW);
canvas.clipPath(mClipPath);
super.onDraw(canvas);
canvas.restoreToCount(saveCount);
}
}
/* A task view */
public class TaskView extends FrameLayout implements View.OnClickListener, Task.TaskCallbacks {
/** The TaskView callbacks */
interface TaskViewCallbacks {
public void onTaskIconClicked(TaskView tv);
// public void onTaskViewReboundToTask(TaskView tv, Task t);
}
Task mTask;
TaskThumbnailView mThumbnailView;
TaskIconView mIconView;
TaskViewCallbacks mCb;
public TaskView(Context context) {
super(context);
mThumbnailView = new TaskThumbnailView(context);
mIconView = new TaskIconView(context);
mIconView.setOnClickListener(this);
addView(mThumbnailView);
addView(mIconView);
RecentsConfiguration config = RecentsConfiguration.getInstance();
int barHeight = config.pxFromDp(Constants.Values.TaskView.TaskBarHeightDps);
int iconSize = config.pxFromDp(Constants.Values.TaskView.TaskIconSizeDps);
int offset = barHeight - (iconSize / 2);
// XXX: Lets keep the icon in the corner for the time being
offset = iconSize / 4;
/*
((LayoutParams) mThumbnailView.getLayoutParams()).leftMargin = barHeight / 2;
((LayoutParams) mThumbnailView.getLayoutParams()).rightMargin = barHeight / 2;
((LayoutParams) mThumbnailView.getLayoutParams()).bottomMargin = barHeight;
*/
((LayoutParams) mIconView.getLayoutParams()).gravity = Gravity.END;
((LayoutParams) mIconView.getLayoutParams()).width = iconSize;
((LayoutParams) mIconView.getLayoutParams()).height = iconSize;
((LayoutParams) mIconView.getLayoutParams()).topMargin = offset;
((LayoutParams) mIconView.getLayoutParams()).rightMargin = offset;
}
/** Set callback */
@ -284,54 +141,41 @@ public class TaskView extends FrameLayout implements View.OnClickListener, Task.
/** Animates this task view as it enters recents */
public void animateOnEnterRecents() {
if (Constants.Values.TaskView.AnimateFrontTaskIconOnEnterUseClip) {
mIconView.setCircularClipRadius(0f);
mIconView.animateCircularClip(true, 1f,
Constants.Values.TaskView.Animation.TaskIconOnEnterDuration,
300, new AccelerateInterpolator(), null);
} else {
RecentsConfiguration config = RecentsConfiguration.getInstance();
int translate = config.pxFromDp(10);
mIconView.setScaleX(1.25f);
mIconView.setScaleY(1.25f);
mIconView.setAlpha(0f);
mIconView.setTranslationX(translate / 2);
mIconView.setTranslationY(-translate);
mIconView.animate()
.alpha(1f)
.scaleX(1f)
.scaleY(1f)
.translationX(0)
.translationY(0)
.setStartDelay(235)
.setDuration(Constants.Values.TaskView.Animation.TaskIconOnEnterDuration)
.withLayer()
.start();
}
RecentsConfiguration config = RecentsConfiguration.getInstance();
int translate = config.pxFromDp(10);
mBarView.setScaleX(1.25f);
mBarView.setScaleY(1.25f);
mBarView.setAlpha(0f);
mBarView.setTranslationX(translate / 2);
mBarView.setTranslationY(-translate);
mBarView.animate()
.alpha(1f)
.scaleX(1f)
.scaleY(1f)
.translationX(0)
.translationY(0)
.setStartDelay(235)
.setDuration(Constants.Values.TaskView.Animation.TaskIconOnEnterDuration)
.withLayer()
.start();
}
/** Animates this task view as it exits recents */
public void animateOnLeavingRecents(final Runnable r) {
if (Constants.Values.TaskView.AnimateFrontTaskIconOnLeavingUseClip) {
mIconView.animateCircularClip(false, 0f,
Constants.Values.TaskView.Animation.TaskIconOnLeavingDuration, 0,
new DecelerateInterpolator(),
new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
r.run();
}
});
} else {
mIconView.animate()
.alpha(0f)
.setStartDelay(0)
.setDuration(Constants.Values.TaskView.Animation.TaskIconOnLeavingDuration)
.setInterpolator(new DecelerateInterpolator())
.withLayer()
.withEndAction(r)
.start();
}
RecentsConfiguration config = RecentsConfiguration.getInstance();
int translate = config.pxFromDp(10);
mBarView.animate()
.alpha(0f)
.scaleX(1.1f)
.scaleY(1.1f)
.translationX(translate / 2)
.translationY(-translate)
.setStartDelay(0)
.setDuration(Constants.Values.TaskView.Animation.TaskIconOnLeavingDuration)
.setInterpolator(new DecelerateInterpolator())
.withLayer()
.withEndAction(r)
.start();
}
/** Returns the rect we want to clip (it may not be the full rect) */
@ -370,17 +214,23 @@ public class TaskView extends FrameLayout implements View.OnClickListener, Task.
@Override
public void onTaskDataLoaded(boolean reloadingTaskData) {
// Bind each of the views to the new task data
mThumbnailView.rebindToTask(mTask, reloadingTaskData);
mIconView.rebindToTask(mTask, reloadingTaskData);
if (mThumbnailView != null && mBarView != null) {
// Bind each of the views to the new task data
mThumbnailView.rebindToTask(mTask, reloadingTaskData);
mBarView.rebindToTask(mTask, reloadingTaskData);
}
mTaskDataLoaded = true;
}
@Override
public void onTaskDataUnloaded() {
// Unbind each of the views from the task data and remove the task callback
mTask.setCallbacks(null);
mThumbnailView.unbindFromTask();
mIconView.unbindFromTask();
if (mThumbnailView != null && mBarView != null) {
// Unbind each of the views from the task data and remove the task callback
mTask.setCallbacks(null);
mThumbnailView.unbindFromTask();
mBarView.unbindFromTask();
}
mTaskDataLoaded = false;
}
@Override