Adding reveal transition to show app-overlay.

- Instead of long-pressing the icon to launch into app info directly,
  this will mirror notifications and reveal a space that can show the
  app name and a link to app info.

Change-Id: I91c5839719b030a65744f5e677a436e9c719c578
This commit is contained in:
Winson
2016-01-21 14:39:23 -08:00
parent b433c5be01
commit c5ef63f4e9
12 changed files with 332 additions and 67 deletions

View File

@@ -0,0 +1,24 @@
<!--
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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48.0dp"
android:height="48.0dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="@color/recents_task_bar_dark_icon_color"
android:pathData="M12.000000,2.000000C6.500000,2.000000 2.000000,6.500000 2.000000,12.000000s4.500000,10.000000 10.000000,10.000000c5.500000,0.000000 10.000000,-4.500000 10.000000,-10.000000S17.500000,2.000000 12.000000,2.000000zM13.000000,17.000000l-2.000000,0.000000l0.000000,-6.000000l2.000000,0.000000L13.000000,17.000000zM13.000000,9.000000l-2.000000,0.000000L11.000000,7.000000l2.000000,0.000000L13.000000,9.000000z"/>
</vector>

View File

@@ -0,0 +1,24 @@
<!--
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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48.0dp"
android:height="48.0dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:pathData="M12.000000,2.000000C6.500000,2.000000 2.000000,6.500000 2.000000,12.000000s4.500000,10.000000 10.000000,10.000000c5.500000,0.000000 10.000000,-4.500000 10.000000,-10.000000S17.500000,2.000000 12.000000,2.000000zM13.000000,17.000000l-2.000000,0.000000l0.000000,-6.000000l2.000000,0.000000L13.000000,17.000000zM13.000000,9.000000l-2.000000,0.000000L11.000000,7.000000l2.000000,0.000000L13.000000,9.000000z"
android:fillColor="#FFFFFF"/>
</vector>

View File

@@ -64,12 +64,19 @@
android:background="@drawable/recents_button_bg"
android:visibility="invisible"
android:src="@drawable/recents_dismiss_light" />
<ProgressBar
android:id="@+id/focus_timer_indicator"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_gravity="bottom"
android:indeterminateOnly="false"
android:visibility="invisible" />
<!-- The progress indicator shows if auto-paging is enabled -->
<ViewStub android:id="@+id/focus_timer_indicator_stub"
android:inflatedId="@+id/focus_timer_indicator"
android:layout="@layout/recents_task_view_header_progress_bar"
android:layout_width="match_parent"
android:layout_height="5dp"
android:layout_gravity="bottom" />
<!-- The app overlay shows as the user long-presses on the app icon -->
<ViewStub android:id="@+id/app_overlay_stub"
android:inflatedId="@+id/app_overlay"
android:layout="@layout/recents_task_view_header_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.android.systemui.recents.views.TaskViewHeader>

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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.
-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
<com.android.systemui.recents.views.FixedSizeImageView
android:id="@+id/app_icon"
android:contentDescription="@string/recents_app_info_button_label"
android:layout_width="@dimen/recents_task_view_application_icon_size"
android:layout_height="@dimen/recents_task_view_application_icon_size"
android:layout_marginStart="8dp"
android:layout_gravity="center_vertical|start"
android:padding="8dp" />
<TextView
android:id="@+id/app_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|start"
android:layout_marginStart="64dp"
android:layout_marginEnd="112dp"
android:textSize="16sp"
android:textColor="#ffffffff"
android:text="@string/recents_empty_message"
android:fontFamily="sans-serif-medium"
android:singleLine="true"
android:maxLines="2"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
<com.android.systemui.recents.views.FixedSizeImageView
android:id="@+id/app_info"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginEnd="4dp"
android:layout_gravity="center_vertical|end"
android:padding="12dp"
android:background="@drawable/recents_button_bg"
android:src="@drawable/recents_info_light" />
</FrameLayout>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 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.
-->
<ProgressBar
xmlns:android="http://schemas.android.com/apk/res/android"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:indeterminateOnly="false"
android:visibility="gone" />

View File

@@ -144,7 +144,6 @@ public class RecentsHistoryAdapter extends RecyclerView.Adapter<RecentsHistoryAd
private Context mContext;
private LayoutInflater mLayoutInflater;
private final List<Task> mTasks = new ArrayList<>();
private final List<Row> mRows = new ArrayList<>();
private final SparseIntArray mTaskRowCount = new SparseIntArray();
private TaskStack mStack;

View File

@@ -30,6 +30,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
@@ -554,39 +555,41 @@ public class SystemServicesProxy {
}
}
/** Returns the activity label */
public String getActivityLabel(ActivityInfo info) {
/**
* Returns the activity label, badging if necessary.
*/
public String getBadgedActivityLabel(ActivityInfo info, int userId) {
if (mPm == null) return null;
// If we are mocking, then return a mock label
if (RecentsDebugFlags.Static.EnableSystemServicesProxy) {
return "Recent Task";
return "Recent Task: " + userId;
}
return info.loadLabel(mPm).toString();
return getBadgedLabel(info.loadLabel(mPm).toString(), userId);
}
/** Returns the application label */
public String getApplicationLabel(Intent baseIntent, int userId) {
/**
* Returns the application label, badging if necessary.
*/
public String getBadgedApplicationLabel(ApplicationInfo appInfo, int userId) {
if (mPm == null) return null;
// If we are mocking, then return a mock label
if (RecentsDebugFlags.Static.EnableSystemServicesProxy) {
return "Recent Task";
return "Recent Task App: " + userId;
}
ResolveInfo ri = mPm.resolveActivityAsUser(baseIntent, 0, userId);
CharSequence label = (ri != null) ? ri.loadLabel(mPm) : null;
return (label != null) ? label.toString() : null;
return getBadgedLabel(appInfo.loadLabel(mPm).toString(), userId);
}
/** Returns the content description for a given task */
public String getContentDescription(Intent baseIntent, int userId, String activityLabel,
Resources res) {
String applicationLabel = getApplicationLabel(baseIntent, userId);
if (applicationLabel == null) {
return getBadgedLabel(activityLabel, userId);
}
/**
* Returns the content description for a given task, badging it if necessary. The content
* description joins the app and activity labels.
*/
public String getBadgedContentDescription(ActivityInfo info, int userId, Resources res) {
String activityLabel = info.loadLabel(mPm).toString();
String applicationLabel = info.applicationInfo.loadLabel(mPm).toString();
String badgedApplicationLabel = getBadgedLabel(applicationLabel, userId);
return applicationLabel.equals(activityLabel) ? badgedApplicationLabel
: res.getString(R.string.accessibility_recents_task_header,
@@ -609,6 +612,22 @@ public class SystemServicesProxy {
return getBadgedIcon(icon, userId);
}
/**
* Returns the application icon for the ApplicationInfo for a user, badging if
* necessary.
*/
public Drawable getBadgedApplicationIcon(ApplicationInfo appInfo, int userId) {
if (mPm == null) return null;
// If we are mocking, then return a mock label
if (RecentsDebugFlags.Static.EnableSystemServicesProxy) {
return new ColorDrawable(0xFF666666);
}
Drawable icon = appInfo.loadIcon(mPm);
return getBadgedIcon(icon, userId);
}
/**
* Returns the task description icon, loading and badging it if it necessary.
*/

View File

@@ -162,7 +162,7 @@ public class RecentsTaskLoadPlan {
// Load the title, icon, and color
String title = loader.getAndUpdateActivityTitle(taskKey, t.taskDescription);
String contentDescription = loader.getAndUpdateContentDescription(taskKey, title, res);
String contentDescription = loader.getAndUpdateContentDescription(taskKey, res);
String dismissDescription = String.format(dismissDescFormat, contentDescription);
Drawable icon = isStackTask
? loader.getAndUpdateActivityIcon(taskKey, t.taskDescription, res, false)

View File

@@ -436,7 +436,7 @@ public class RecentsTaskLoader {
// All short paths failed, load the label from the activity info and cache it
ActivityInfo activityInfo = getAndUpdateActivityInfo(taskKey);
if (activityInfo != null) {
label = ssp.getActivityLabel(activityInfo);
label = ssp.getBadgedActivityLabel(activityInfo, taskKey.userId);
mActivityLabelCache.put(taskKey, label);
return label;
}
@@ -449,8 +449,7 @@ public class RecentsTaskLoader {
* Returns the cached task content description if the task key is not expired, updating the
* cache if it is.
*/
String getAndUpdateContentDescription(Task.TaskKey taskKey, String activityLabel,
Resources res) {
String getAndUpdateContentDescription(Task.TaskKey taskKey, Resources res) {
SystemServicesProxy ssp = Recents.getSystemServices();
// Return the cached content description if it exists
@@ -458,13 +457,11 @@ public class RecentsTaskLoader {
if (label != null) {
return label;
}
// If the given activity label is empty, don't compute or cache the content description
if (activityLabel.isEmpty()) {
return "";
}
label = ssp.getContentDescription(taskKey.baseIntent, taskKey.userId, activityLabel, res);
if (label != null) {
// All short paths failed, load the label from the activity info and cache it
ActivityInfo activityInfo = getAndUpdateActivityInfo(taskKey);
if (activityInfo != null) {
label = ssp.getBadgedContentDescription(activityInfo, taskKey.userId, res);
mContentDescriptionCache.put(taskKey, label);
return label;
}

View File

@@ -1549,7 +1549,10 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
// Poke the doze trigger on user interaction
mUIDozeTrigger.poke();
if (event.showTimerIndicator && mFocusedTask != null) {
getChildViewForTask(mFocusedTask).getHeaderView().cancelFocusTimerIndicator();
TaskView tv = getChildViewForTask(mFocusedTask);
if (tv != null) {
tv.getHeaderView().cancelFocusTimerIndicator();
}
}
}

View File

@@ -162,6 +162,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks,
/** Resets this TaskView for reuse. */
void reset() {
mHeaderView.reset();
resetViewProperties();
resetNoUserInteractionState();
setClipViewInStack(false);

View File

@@ -16,22 +16,27 @@
package com.android.systemui.recents.views;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
import android.support.v4.graphics.ColorUtils;
import android.os.CountDownTimer;
import android.support.v4.graphics.ColorUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.ViewStub;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
@@ -39,10 +44,10 @@ import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.R;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsDebugFlags;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.LaunchTaskEvent;
import com.android.systemui.recents.events.ui.ShowApplicationInfoEvent;
@@ -59,6 +64,8 @@ public class TaskViewHeader extends FrameLayout
implements View.OnClickListener, View.OnLongClickListener {
private static final float HIGHLIGHT_LIGHTNESS_INCREMENT = 0.125f;
private static final float OVERLAY_LIGHTNESS_INCREMENT = -0.0625f;
private static final int OVERLAY_REVEAL_DURATION = 250;
private static final long FOCUS_INDICATOR_INTERVAL_MS = 30;
/**
@@ -69,8 +76,6 @@ public class TaskViewHeader extends FrameLayout
private Paint mHighlightPaint = new Paint();
private Paint mBackgroundPaint = new Paint();
private float[] mTmpHSL = new float[3];
public HighlightColorDrawable() {
mBackgroundPaint.setColor(Color.argb(255, 0, 0, 0));
mBackgroundPaint.setAntiAlias(true);
@@ -122,11 +127,16 @@ public class TaskViewHeader extends FrameLayout
Task mTask;
// Header views
ImageView mMoveTaskButton;
ImageView mDismissButton;
ImageView mIconView;
TextView mTitleView;
int mMoveTaskTargetStackId = INVALID_STACK_ID;
ImageView mMoveTaskButton;
ImageView mDismissButton;
ViewStub mAppOverlayViewStub;
FrameLayout mAppOverlayView;
ImageView mAppIconView;
ImageView mAppInfoView;
TextView mAppTitleView;
ViewStub mFocusTimerIndicatorStub;
ProgressBar mFocusTimerIndicator;
// Header drawables
@@ -140,21 +150,26 @@ public class TaskViewHeader extends FrameLayout
Drawable mDarkFreeformIcon;
Drawable mLightFullscreenIcon;
Drawable mDarkFullscreenIcon;
Drawable mLightInfoIcon;
Drawable mDarkInfoIcon;
int mTaskBarViewLightTextColor;
int mTaskBarViewDarkTextColor;
int mMoveTaskTargetStackId = INVALID_STACK_ID;
// Header background
private HighlightColorDrawable mBackground;
private HighlightColorDrawable mOverlayBackground;
private float[] mTmpHSL = new float[3];
// Header dim, which is only used when task view hardware layers are not used
private Paint mDimLayerPaint = new Paint();
Interpolator mFastOutSlowInInterpolator;
Interpolator mFastOutLinearInInterpolator;
Interpolator mLinearOutSlowInInterpolator;
long mFocusIndicatorProgress;
private CountDownTimer mFocusTimerCountDown;
long mFocusTimerDuration;
private long mFocusTimerDuration;
public TaskViewHeader(Context context) {
this(context, null);
@@ -184,36 +199,45 @@ public class TaskViewHeader extends FrameLayout
mDarkFreeformIcon = context.getDrawable(R.drawable.recents_move_task_freeform_dark);
mLightFullscreenIcon = context.getDrawable(R.drawable.recents_move_task_fullscreen_light);
mDarkFullscreenIcon = context.getDrawable(R.drawable.recents_move_task_fullscreen_dark);
mLightInfoIcon = context.getDrawable(R.drawable.recents_info_light);
mDarkInfoIcon = context.getDrawable(R.drawable.recents_info_dark);
mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
com.android.internal.R.interpolator.fast_out_slow_in);
mFastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context,
com.android.internal.R.interpolator.fast_out_linear_in);
mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
com.android.internal.R.interpolator.linear_out_slow_in);
// Configure the background and dim
mBackground = new HighlightColorDrawable();
mBackground.setColorAndDim(Color.argb(255, 0, 0, 0), 0f);
setBackground(mBackground);
mOverlayBackground = new HighlightColorDrawable();
mDimLayerPaint.setColor(Color.argb(255, 0, 0, 0));
mDimLayerPaint.setAntiAlias(true);
mFocusTimerDuration = res.getInteger(R.integer.recents_auto_advance_duration);
}
/**
* Resets this header along with the TaskView.
*/
public void reset() {
hideAppOverlay(true /* immediate */);
}
@Override
protected void onFinishInflate() {
// Initialize the icon and description views
mIconView = (ImageView) findViewById(R.id.icon);
mIconView.setClickable(false);
mIconView.setOnLongClickListener(this);
mTitleView = (TextView) findViewById(R.id.title);
mDismissButton = (ImageView) findViewById(R.id.dismiss_task);
mDismissButton.setOnClickListener(this);
mMoveTaskButton = (ImageView) findViewById(R.id.move_task);
mFocusTimerIndicator = (ProgressBar) findViewById(R.id.focus_timer_indicator);
// Hide the backgrounds if they are ripple drawables
if (mIconView.getBackground() instanceof RippleDrawable) {
mIconView.setBackground(null);
}
mFocusTimerIndicatorStub = (ViewStub) findViewById(R.id.focus_timer_indicator_stub);
mAppOverlayViewStub = (ViewStub) findViewById(R.id.app_overlay_stub);
}
/**
@@ -274,11 +298,6 @@ public class TaskViewHeader extends FrameLayout
invalidate();
}
@Override
protected boolean verifyDrawable(Drawable who) {
return super.verifyDrawable(who) || (who == mBackground);
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
@@ -290,6 +309,10 @@ public class TaskViewHeader extends FrameLayout
/** Starts the focus timer. */
public void startFocusTimerIndicator() {
if (mFocusTimerIndicator == null) {
return;
}
mFocusTimerIndicator.setVisibility(View.VISIBLE);
mFocusTimerIndicator.setMax((int) mFocusTimerDuration);
if (mFocusTimerCountDown == null) {
@@ -310,7 +333,11 @@ public class TaskViewHeader extends FrameLayout
/** Cancels the focus timer. */
public void cancelFocusTimerIndicator() {
if (mFocusTimerCountDown != null && mFocusTimerIndicator != null) {
if (mFocusTimerIndicator == null) {
return;
}
if (mFocusTimerCountDown != null) {
mFocusTimerCountDown.cancel();
mFocusTimerIndicator.setProgress(0);
mFocusTimerIndicator.setVisibility(View.INVISIBLE);
@@ -339,6 +366,10 @@ public class TaskViewHeader extends FrameLayout
private void updateBackgroundColor(float dimAlpha) {
if (mTask != null) {
mBackground.setColorAndDim(mTask.colorPrimary, dimAlpha);
// TODO: Consider using the saturation of the color to adjust the lightness as well
ColorUtils.colorToHSL(mTask.colorPrimary, mTmpHSL);
mTmpHSL[2] = Math.min(1f, mTmpHSL[2] + OVERLAY_LIGHTNESS_INCREMENT * (1.0f - dimAlpha));
mOverlayBackground.setColorAndDim(ColorUtils.HSLToColor(mTmpHSL), dimAlpha);
mDimLayerPaint.setAlpha((int) (dimAlpha * 255));
}
}
@@ -384,10 +415,15 @@ public class TaskViewHeader extends FrameLayout
mMoveTaskButton.setOnClickListener(this);
}
mFocusTimerIndicator.getProgressDrawable()
.setColorFilter(
getSecondaryColor(t.colorPrimary, t.useLightOnPrimaryColor),
PorterDuff.Mode.SRC_IN);
if (Recents.getDebugFlags().isFastToggleIndicatorEnabled()) {
if (mFocusTimerIndicator == null) {
mFocusTimerIndicator = (ProgressBar) mFocusTimerIndicatorStub.inflate();
}
mFocusTimerIndicator.getProgressDrawable()
.setColorFilter(
getSecondaryColor(t.colorPrimary, t.useLightOnPrimaryColor),
PorterDuff.Mode.SRC_IN);
}
// In accessibility, a single click on the focused app info button will show it
if (ssp.isTouchExplorationEnabled()) {
@@ -449,8 +485,11 @@ public class TaskViewHeader extends FrameLayout
@Override
public void onClick(View v) {
if (v == mIconView) {
// In accessibility, a single click on the focused app info button will show it
EventBus.getDefault().send(new ShowApplicationInfoEvent(mTask));
SystemServicesProxy ssp = Recents.getSystemServices();
if (ssp.isTouchExplorationEnabled()) {
// In accessibility, a single click on the focused app info button will show it
EventBus.getDefault().send(new ShowApplicationInfoEvent(mTask));
}
} else if (v == mDismissButton) {
TaskView tv = Utilities.findParent(this, TaskView.class);
tv.dismissTask();
@@ -465,15 +504,92 @@ public class TaskViewHeader extends FrameLayout
: new Rect();
EventBus.getDefault().send(new LaunchTaskEvent(tv, mTask, bounds,
mMoveTaskTargetStackId, false));
} else if (v == mAppInfoView) {
EventBus.getDefault().send(new ShowApplicationInfoEvent(mTask));
} else if (v == mAppIconView) {
hideAppOverlay(false /* immediate */);
}
}
@Override
public boolean onLongClick(View v) {
if (v == mIconView) {
EventBus.getDefault().send(new ShowApplicationInfoEvent(mTask));
showAppOverlay();
return true;
} else if (v == mAppIconView) {
hideAppOverlay(false /* immediate */);
return true;
}
return false;
}
/**
* Shows the application overlay.
*/
private void showAppOverlay() {
// Skip early if the task is invalid
SystemServicesProxy ssp = Recents.getSystemServices();
ComponentName cn = mTask.key.getComponent();
int userId = mTask.key.userId;
ActivityInfo activityInfo = ssp.getActivityInfo(cn, userId);
if (activityInfo == null) {
return;
}
// Inflate the overlay if necessary
if (mAppOverlayView == null) {
mAppOverlayView = (FrameLayout) mAppOverlayViewStub.inflate();
mAppOverlayView.setBackground(mOverlayBackground);
mAppIconView = (ImageView) mAppOverlayView.findViewById(R.id.app_icon);
mAppIconView.setOnClickListener(this);
mAppIconView.setOnLongClickListener(this);
mAppInfoView = (ImageView) mAppOverlayView.findViewById(R.id.app_info);
mAppInfoView.setOnClickListener(this);
mAppTitleView = (TextView) mAppOverlayView.findViewById(R.id.app_title);
}
// Update the overlay contents for the current app
mAppTitleView.setText(ssp.getBadgedApplicationLabel(activityInfo.applicationInfo, userId));
mAppIconView.setImageDrawable(ssp.getBadgedApplicationIcon(activityInfo.applicationInfo, userId));
mAppInfoView.setImageDrawable(mTask.useLightOnPrimaryColor
? mLightInfoIcon
: mDarkInfoIcon);
mAppOverlayView.setVisibility(View.VISIBLE);
int x = mIconView.getLeft() + mIconView.getWidth() / 2;
int y = mIconView.getTop() + mIconView.getHeight() / 2;
Animator revealAnim = ViewAnimationUtils.createCircularReveal(mAppOverlayView, x, y, 0,
getWidth());
revealAnim.setDuration(OVERLAY_REVEAL_DURATION);
revealAnim.setInterpolator(mLinearOutSlowInInterpolator);
revealAnim.start();
}
/**
* Hide the application overlay.
*/
private void hideAppOverlay(boolean immediate) {
// Skip if we haven't even loaded the overlay yet
if (mAppOverlayView == null) {
return;
}
if (immediate) {
mAppOverlayView.setVisibility(View.GONE);
} else {
int x = mIconView.getLeft() + mIconView.getWidth() / 2;
int y = mIconView.getTop() + mIconView.getHeight() / 2;
Animator revealAnim = ViewAnimationUtils.createCircularReveal(mAppOverlayView, x, y,
getWidth(), 0);
revealAnim.setDuration(OVERLAY_REVEAL_DURATION);
revealAnim.setInterpolator(mLinearOutSlowInInterpolator);
revealAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mAppOverlayView.setVisibility(View.GONE);
}
});
revealAnim.start();
}
}
}