Moving task view layout into resource.
- Using new activity icon/labels Change-Id: If27bf60d2df75813213e9f3095baeb03085da8f7
This commit is contained in:
49
packages/SystemUI/res/layout/recents_task_view.xml
Normal file
49
packages/SystemUI/res/layout/recents_task_view.xml
Normal 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>
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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("");
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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
|
||||
|
Reference in New Issue
Block a user