Methods Summary |
---|
void | animateDimToProgress(int delay, int duration, Animator.AnimatorListener postAnimRunnable)Animates the dim to the task progress.
// Animate the dim into view as well
int toDim = getDimFromTaskProgress();
if (toDim != getDim()) {
ObjectAnimator anim = ObjectAnimator.ofInt(TaskView.this, "dim", toDim);
anim.setStartDelay(delay);
anim.setDuration(duration);
if (postAnimRunnable != null) {
anim.addListener(postAnimRunnable);
}
anim.start();
}
|
void | dismissTask()Dismisses this task.
// Animate out the view and call the callback
final TaskView tv = this;
startDeleteTaskAnimation(new Runnable() {
@Override
public void run() {
if (mCb != null) {
mCb.onTaskViewDismissed(tv);
}
}
});
|
void | enableFocusAnimations()Enables all focus animations.
boolean wasFocusAnimationsEnabled = mFocusAnimationsEnabled;
mFocusAnimationsEnabled = true;
if (mIsFocused && !wasFocusAnimationsEnabled) {
// Re-notify the header if we were focused and animations were not previously enabled
mHeaderView.onTaskViewFocusChanged(true, true);
}
|
public void | fadeInActionButton(int delay, int duration)
// Hide the action button
mActionButtonView.setAlpha(0f);
// Animate the action button in
mActionButtonView.animate().alpha(1f)
.setStartDelay(delay)
.setDuration(duration)
.setInterpolator(PhoneStatusBar.ALPHA_IN)
.withLayer()
.start();
|
public int | getDim()Returns the current dim.
return mDimAlpha;
|
int | getDimFromTaskProgress()Compute the dim as a function of the scale of this view.
float dim = mMaxDimScale * mDimInterpolator.getInterpolation(1f - mTaskProgress);
return (int) (dim * 255);
|
com.android.systemui.recents.model.Task | getTask()Gets the task
return mTask;
|
public float | getTaskProgress()Returns the current task progress.
return mTaskProgress;
|
AnimateableViewBounds | getViewBounds()Returns the view bounds.
return mViewBounds;
|
public boolean | isFocusedTask()Returns whether we have explicitly been focused.
return mIsFocused || isFocused();
|
public void | onClick(android.view.View v)View.OnClickListener Implementation
final TaskView tv = this;
final boolean delayViewClick = (v != this) && (v != mActionButtonView);
if (delayViewClick) {
// We purposely post the handler delayed to allow for the touch feedback to draw
postDelayed(new Runnable() {
@Override
public void run() {
if (Constants.DebugFlags.App.EnableTaskFiltering && v == mHeaderView.mApplicationIcon) {
if (mCb != null) {
mCb.onTaskViewAppIconClicked(tv);
}
} else if (v == mHeaderView.mDismissButton) {
dismissTask();
}
}
}, 125);
} else {
if (v == mActionButtonView) {
// Reset the translation of the action button before we animate it out
mActionButtonView.setTranslationZ(0f);
}
if (mCb != null) {
mCb.onTaskViewClicked(tv, tv.getTask(), (v == mActionButtonView));
}
}
|
protected void | onFinishInflate()
// Bind the views
mContent = findViewById(R.id.task_view_content);
mHeaderView = (TaskViewHeader) findViewById(R.id.task_view_bar);
mThumbnailView = (TaskViewThumbnail) findViewById(R.id.task_view_thumbnail);
mThumbnailView.updateClipToTaskBar(mHeaderView);
mActionButtonView = findViewById(R.id.lock_to_app_fab);
mActionButtonView.setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
// Set the outline to match the FAB background
outline.setOval(0, 0, mActionButtonView.getWidth(), mActionButtonView.getHeight());
}
});
mActionButtonTranslationZ = mActionButtonView.getTranslationZ();
|
protected void | onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect)Updates the explicitly focused state when the view focus changes.
super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
if (!gainFocus) {
unsetFocusedTask();
}
|
public boolean | onLongClick(android.view.View v)View.OnLongClickListener Implementation
if (v == mHeaderView.mApplicationIcon) {
if (mCb != null) {
mCb.onTaskViewAppInfoClicked(this);
return true;
}
}
return false;
|
protected void | onMeasure(int widthMeasureSpec, int heightMeasureSpec)
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int widthWithoutPadding = width - mPaddingLeft - mPaddingRight;
int heightWithoutPadding = height - mPaddingTop - mPaddingBottom;
// Measure the content
mContent.measure(MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY));
// Measure the bar view, and action button
mHeaderView.measure(MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(mConfig.taskBarHeight, MeasureSpec.EXACTLY));
mActionButtonView.measure(
MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(heightWithoutPadding, MeasureSpec.AT_MOST));
// Measure the thumbnail to be square
mThumbnailView.measure(
MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY));
setMeasuredDimension(width, height);
invalidateOutline();
|
public void | onTaskBound(com.android.systemui.recents.model.Task t)Binds this task view to the task
mTask = t;
mTask.setCallbacks(this);
// Hide the action button if lock to app is disabled for this view
int lockButtonVisibility = (!t.lockToTaskEnabled || !t.lockToThisTask) ? GONE : VISIBLE;
if (mActionButtonView.getVisibility() != lockButtonVisibility) {
mActionButtonView.setVisibility(lockButtonVisibility);
requestLayout();
}
|
public void | onTaskDataLoaded()
if (mThumbnailView != null && mHeaderView != null) {
// Bind each of the views to the new task data
mThumbnailView.rebindToTask(mTask);
mHeaderView.rebindToTask(mTask);
// Rebind any listeners
mHeaderView.mApplicationIcon.setOnClickListener(this);
mHeaderView.mDismissButton.setOnClickListener(this);
mActionButtonView.setOnClickListener(this);
if (Constants.DebugFlags.App.EnableDevAppInfoOnLongPress) {
if (mConfig.developerOptionsEnabled) {
mHeaderView.mApplicationIcon.setOnLongClickListener(this);
}
}
}
mTaskDataLoaded = true;
|
public void | onTaskDataUnloaded()
if (mThumbnailView != null && mHeaderView != null) {
// Unbind each of the views from the task data and remove the task callback
mTask.setCallbacks(null);
mThumbnailView.unbindFromTask();
mHeaderView.unbindFromTask();
// Unbind any listeners
mHeaderView.mApplicationIcon.setOnClickListener(null);
mHeaderView.mDismissButton.setOnClickListener(null);
mActionButtonView.setOnClickListener(null);
if (Constants.DebugFlags.App.EnableDevAppInfoOnLongPress) {
mHeaderView.mApplicationIcon.setOnLongClickListener(null);
}
}
mTaskDataLoaded = false;
|
void | prepareEnterRecentsAnimation(boolean isTaskViewLaunchTargetTask, boolean occludesLaunchTarget, int offscreenY)Prepares this task view for the enter-recents animations. This is called earlier in the
first layout because the actual animation into recents may take a long time.
int initialDim = getDim();
if (mConfig.launchedHasConfigurationChanged) {
// Just load the views as-is
} else if (mConfig.launchedFromAppWithThumbnail) {
if (isTaskViewLaunchTargetTask) {
// Set the dim to 0 so we can animate it in
initialDim = 0;
// Hide the action button
mActionButtonView.setAlpha(0f);
} else if (occludesLaunchTarget) {
// Move the task view off screen (below) so we can animate it in
setTranslationY(offscreenY);
}
} else if (mConfig.launchedFromHome) {
// Move the task view off screen (below) so we can animate it in
setTranslationY(offscreenY);
setTranslationZ(0);
setScaleX(1f);
setScaleY(1f);
}
// Apply the current dim
setDim(initialDim);
// Prepare the thumbnail view alpha
mThumbnailView.prepareEnterRecentsAnimation(isTaskViewLaunchTargetTask);
|
void | prepareTaskTransformForFilterTaskHidden(TaskViewTransform toTransform)When we are un/filtering, this method will set up the transform that we are animating to,
in order to hide the task.
// Fade the view out and slide it away
toTransform.alpha = 0f;
toTransform.translationY += 200;
toTransform.translationZ = 0;
|
void | prepareTaskTransformForFilterTaskVisible(TaskViewTransform fromTransform)When we are un/filtering, this method will setup the transform that we are animating from,
in order to show the task.
// Fade the view in
fromTransform.alpha = 0f;
|
void | reset()Resets this TaskView for reuse.
resetViewProperties();
resetNoUserInteractionState();
setClipViewInStack(false);
setCallbacks(null);
|
void | resetNoUserInteractionState()Resets the state tracking that the user has not interacted with the stack after a certain time.
mHeaderView.resetNoUserInteractionState();
|
void | resetViewProperties()Resets this view's properties
setDim(0);
setLayerType(View.LAYER_TYPE_NONE, null);
TaskViewTransform.reset(this);
if (mActionButtonView != null) {
mActionButtonView.setScaleX(1f);
mActionButtonView.setScaleY(1f);
mActionButtonView.setAlpha(1f);
mActionButtonView.setTranslationZ(mActionButtonTranslationZ);
}
|
void | setCallbacks(com.android.systemui.recents.views.TaskView$TaskViewCallbacks cb)Set callback
mCb = cb;
|
void | setClipViewInStack(boolean clip)Sets whether this view should be clipped, or clipped against.
if (clip != mClipViewInStack) {
mClipViewInStack = clip;
if (mCb != null) {
mCb.onTaskViewClipStateChanged(this);
}
}
|
public void | setDim(int dim)Returns the current dim.
mDimAlpha = dim;
if (mConfig.useHardwareLayers) {
// Defer setting hardware layers if we have not yet measured, or there is no dim to draw
if (getMeasuredWidth() > 0 && getMeasuredHeight() > 0) {
mDimColorFilter.setColor(Color.argb(mDimAlpha, 0, 0, 0));
mDimLayerPaint.setColorFilter(mDimColorFilter);
mContent.setLayerType(LAYER_TYPE_HARDWARE, mDimLayerPaint);
}
} else {
float dimAlpha = mDimAlpha / 255.0f;
if (mThumbnailView != null) {
mThumbnailView.setDimAlpha(dimAlpha);
}
if (mHeaderView != null) {
mHeaderView.setDimAlpha(dim);
}
}
|
public void | setFocusedTask(boolean animateFocusedState)Sets the focused task explicitly. We need a separate flag because requestFocus() won't happen
if the view is not currently visible, or we are in touch state (where we still want to keep
track of focus).
mIsFocused = true;
if (mFocusAnimationsEnabled) {
// Focus the header bar
mHeaderView.onTaskViewFocusChanged(true, animateFocusedState);
}
// Update the thumbnail alpha with the focus
mThumbnailView.onFocusChanged(true);
// Call the callback
if (mCb != null) {
mCb.onTaskViewFocusChanged(this, true);
}
// Workaround, we don't always want it focusable in touch mode, but we want the first task
// to be focused after the enter-recents animation, which can be triggered from either touch
// or keyboard
setFocusableInTouchMode(true);
requestFocus();
setFocusableInTouchMode(false);
invalidate();
|
void | setNoUserInteractionState()Mark this task view that the user does has not interacted with the stack after a certain time.
mHeaderView.setNoUserInteractionState();
|
public void | setTaskProgress(float p)Sets the current task progress.
mTaskProgress = p;
mViewBounds.setAlpha(p);
updateDimFromTaskProgress();
|
void | setTouchEnabled(boolean enabled)Enables/disables handling touch on this task view.
setOnClickListener(enabled ? this : null);
|
boolean | shouldClipViewInStack()Returns whether this view should be clipped, or any views below should clip against this
view.
return mClipViewInStack && (getVisibility() == View.VISIBLE);
|
void | startDeleteTaskAnimation(java.lang.Runnable r)Animates the deletion of this task view
// Disabling clipping with the stack while the view is animating away
setClipViewInStack(false);
animate().translationX(mConfig.taskViewRemoveAnimTranslationXPx)
.alpha(0f)
.setStartDelay(0)
.setUpdateListener(null)
.setInterpolator(mConfig.fastOutSlowInInterpolator)
.setDuration(mConfig.taskViewRemoveAnimDuration)
.withEndAction(new Runnable() {
@Override
public void run() {
// We just throw this into a runnable because starting a view property
// animation using layers can cause inconsisten results if we try and
// update the layers while the animation is running. In some cases,
// the runnabled passed in may start an animation which also uses layers
// so we defer all this by posting this.
r.run();
// Re-enable clipping with the stack (we will reuse this view)
setClipViewInStack(true);
}
})
.start();
|
void | startEnterRecentsAnimation(ViewAnimation.TaskViewEnterContext ctx)Animates this task view as it enters recents
final TaskViewTransform transform = ctx.currentTaskTransform;
int startDelay = 0;
if (mConfig.launchedFromAppWithThumbnail) {
if (mTask.isLaunchTarget) {
// Animate the dim/overlay
if (Constants.DebugFlags.App.EnableThumbnailAlphaOnFrontmost) {
// Animate the thumbnail alpha before the dim animation (to prevent updating the
// hardware layer)
mThumbnailView.startEnterRecentsAnimation(mConfig.transitionEnterFromAppDelay,
new Runnable() {
@Override
public void run() {
animateDimToProgress(0, mConfig.taskViewEnterFromAppDuration,
ctx.postAnimationTrigger.decrementOnAnimationEnd());
}
});
} else {
// Immediately start the dim animation
animateDimToProgress(mConfig.transitionEnterFromAppDelay,
mConfig.taskViewEnterFromAppDuration,
ctx.postAnimationTrigger.decrementOnAnimationEnd());
}
ctx.postAnimationTrigger.increment();
// Animate the action button in
fadeInActionButton(mConfig.transitionEnterFromAppDelay,
mConfig.taskViewEnterFromAppDuration);
} else {
// Animate the task up if it was occluding the launch target
if (ctx.currentTaskOccludesLaunchTarget) {
setTranslationY(transform.translationY + mConfig.taskViewAffiliateGroupEnterOffsetPx);
setAlpha(0f);
animate().alpha(1f)
.translationY(transform.translationY)
.setStartDelay(mConfig.transitionEnterFromAppDelay)
.setUpdateListener(null)
.setInterpolator(mConfig.fastOutSlowInInterpolator)
.setDuration(mConfig.taskViewEnterFromHomeDuration)
.withEndAction(new Runnable() {
@Override
public void run() {
// Decrement the post animation trigger
ctx.postAnimationTrigger.decrement();
}
})
.start();
ctx.postAnimationTrigger.increment();
}
}
startDelay = mConfig.transitionEnterFromAppDelay;
} else if (mConfig.launchedFromHome) {
// Animate the tasks up
int frontIndex = (ctx.currentStackViewCount - ctx.currentStackViewIndex - 1);
int delay = mConfig.transitionEnterFromHomeDelay +
frontIndex * mConfig.taskViewEnterFromHomeStaggerDelay;
setScaleX(transform.scale);
setScaleY(transform.scale);
if (!mConfig.fakeShadows) {
animate().translationZ(transform.translationZ);
}
animate()
.translationY(transform.translationY)
.setStartDelay(delay)
.setUpdateListener(ctx.updateListener)
.setInterpolator(mConfig.quintOutInterpolator)
.setDuration(mConfig.taskViewEnterFromHomeDuration +
frontIndex * mConfig.taskViewEnterFromHomeStaggerDelay)
.withEndAction(new Runnable() {
@Override
public void run() {
// Decrement the post animation trigger
ctx.postAnimationTrigger.decrement();
}
})
.start();
ctx.postAnimationTrigger.increment();
startDelay = delay;
}
// Enable the focus animations from this point onwards so that they aren't affected by the
// window transitions
postDelayed(new Runnable() {
@Override
public void run() {
enableFocusAnimations();
}
}, startDelay);
|
void | startExitToHomeAnimation(ViewAnimation.TaskViewExitContext ctx)Animates this task view as it leaves recents by pressing home.
animate()
.translationY(ctx.offscreenTranslationY)
.setStartDelay(0)
.setUpdateListener(null)
.setInterpolator(mConfig.fastOutLinearInInterpolator)
.setDuration(mConfig.taskViewExitToHomeDuration)
.withEndAction(ctx.postAnimationTrigger.decrementAsRunnable())
.start();
ctx.postAnimationTrigger.increment();
|
void | startLaunchTaskAnimation(java.lang.Runnable postAnimRunnable, boolean isLaunchingTask, boolean occludesLaunchTarget, boolean lockToTask)Animates this task view as it exits recents
if (isLaunchingTask) {
// Animate the thumbnail alpha back into full opacity for the window animation out
mThumbnailView.startLaunchTaskAnimation(postAnimRunnable);
// Animate the dim
if (mDimAlpha > 0) {
ObjectAnimator anim = ObjectAnimator.ofInt(this, "dim", 0);
anim.setDuration(mConfig.taskViewExitToAppDuration);
anim.setInterpolator(mConfig.fastOutLinearInInterpolator);
anim.start();
}
// Animate the action button away
if (!lockToTask) {
float toScale = 0.9f;
mActionButtonView.animate()
.scaleX(toScale)
.scaleY(toScale);
}
mActionButtonView.animate()
.alpha(0f)
.setStartDelay(0)
.setDuration(mConfig.taskViewExitToAppDuration)
.setInterpolator(mConfig.fastOutLinearInInterpolator)
.withLayer()
.start();
} else {
// Hide the dismiss button
mHeaderView.startLaunchTaskDismissAnimation();
// If this is another view in the task grouping and is in front of the launch task,
// animate it away first
if (occludesLaunchTarget) {
animate().alpha(0f)
.translationY(getTranslationY() + mConfig.taskViewAffiliateGroupEnterOffsetPx)
.setStartDelay(0)
.setUpdateListener(null)
.setInterpolator(mConfig.fastOutLinearInInterpolator)
.setDuration(mConfig.taskViewExitToAppDuration)
.start();
}
}
|
void | startNoUserInteractionAnimation()Animates this task view if the user does not interact with the stack after a certain time.
mHeaderView.startNoUserInteractionAnimation();
|
void | unsetFocusedTask()Unsets the focused task explicitly.
mIsFocused = false;
if (mFocusAnimationsEnabled) {
// Un-focus the header bar
mHeaderView.onTaskViewFocusChanged(false, true);
}
// Update the thumbnail alpha with the focus
mThumbnailView.onFocusChanged(false);
// Call the callback
if (mCb != null) {
mCb.onTaskViewFocusChanged(this, false);
}
invalidate();
|
void | updateDimFromTaskProgress()Update the dim as a function of the scale of this view.
setDim(getDimFromTaskProgress());
|
void | updateViewPropertiesToTaskTransform(TaskViewTransform toTransform, int duration)Synchronizes this view's properties with the task's transform
updateViewPropertiesToTaskTransform(toTransform, duration, null);
|
void | updateViewPropertiesToTaskTransform(TaskViewTransform toTransform, int duration, ValueAnimator.AnimatorUpdateListener updateCallback)
// Apply the transform
toTransform.applyToTaskView(this, duration, mConfig.fastOutSlowInInterpolator, false,
!mConfig.fakeShadows, updateCallback);
// Update the task progress
Utilities.cancelAnimationWithoutCallbacks(mTaskProgressAnimator);
if (duration <= 0) {
setTaskProgress(toTransform.p);
} else {
mTaskProgressAnimator = ObjectAnimator.ofFloat(this, "taskProgress", toTransform.p);
mTaskProgressAnimator.setDuration(duration);
mTaskProgressAnimator.addUpdateListener(mUpdateDimListener);
mTaskProgressAnimator.start();
}
|