Fixing issues with dim not animating, adding dismiss button delay, tweaking empty recents text. (Bug 15431590, 15573497)
Change-Id: I9c11e04cd52f9e000d8ba3e443f2500c9aa7edbb
This commit is contained in:
@@ -21,7 +21,6 @@
|
||||
android:gravity="center"
|
||||
android:textSize="20sp"
|
||||
android:textColor="#ffffffff"
|
||||
android:textStyle="italic"
|
||||
android:text="@string/recents_empty_message"
|
||||
android:fontFamily="sans-serif-light"
|
||||
android:visibility="gone" />
|
||||
@@ -56,6 +56,7 @@
|
||||
android:layout_marginEnd="4dp"
|
||||
android:layout_gravity="center_vertical|end"
|
||||
android:padding="18dp"
|
||||
android:visibility="invisible"
|
||||
android:src="@drawable/recents_dismiss_light" />
|
||||
</com.android.systemui.recents.views.TaskBarView>
|
||||
</com.android.systemui.recents.views.TaskView>
|
||||
|
||||
@@ -108,6 +108,8 @@
|
||||
<!-- milliseconds before the heads up notification accepts touches. -->
|
||||
<integer name="heads_up_sensitivity_delay">700</integer>
|
||||
|
||||
<!-- The duration in seconds to wait before the dismiss buttons are shown. -->
|
||||
<integer name="recents_task_bar_dismiss_delay_seconds">3</integer>
|
||||
<!-- The min animation duration for animating views that are currently visible. -->
|
||||
<integer name="recents_filter_animate_current_views_min_duration">175</integer>
|
||||
<!-- The min animation duration for animating views that are newly visible. -->
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import android.os.Handler;
|
||||
|
||||
/**
|
||||
* A dozer is a class that fires a trigger after it falls asleep. You can occasionally poke it to
|
||||
* wake it up, but it will fall asleep if left untouched.
|
||||
*/
|
||||
public class DozeTrigger {
|
||||
|
||||
Handler mHandler;
|
||||
|
||||
boolean mIsDozing;
|
||||
boolean mHasTriggered;
|
||||
int mDozeDurationSeconds;
|
||||
Runnable mSleepRunnable;
|
||||
|
||||
// Sleep-runnable
|
||||
Runnable mDozeRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mSleepRunnable.run();
|
||||
mIsDozing = false;
|
||||
mHasTriggered = true;
|
||||
}
|
||||
};
|
||||
|
||||
public DozeTrigger(int dozeDurationSeconds, Runnable sleepRunnable) {
|
||||
mHandler = new Handler();
|
||||
mDozeDurationSeconds = dozeDurationSeconds;
|
||||
mSleepRunnable = sleepRunnable;
|
||||
}
|
||||
|
||||
/** Starts dozing. This also resets the trigger flag. */
|
||||
public void startDozing() {
|
||||
poke();
|
||||
mHasTriggered = false;
|
||||
}
|
||||
|
||||
/** Poke this dozer to wake it up for a little bit. */
|
||||
public void poke() {
|
||||
mHandler.removeCallbacks(mDozeRunnable);
|
||||
mHandler.postDelayed(mDozeRunnable, mDozeDurationSeconds * 1000);
|
||||
mIsDozing = true;
|
||||
}
|
||||
|
||||
/** Returns whether we are dozing or not. */
|
||||
public boolean isDozing() {
|
||||
return mIsDozing;
|
||||
}
|
||||
|
||||
/** Returns whether the trigger has fired at least once. */
|
||||
public boolean hasTriggered() {
|
||||
return mHasTriggered;
|
||||
}
|
||||
}
|
||||
@@ -526,6 +526,11 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserInteraction() {
|
||||
mRecentsView.onUserInteraction();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
// If we are mid-animation into Recents, then reverse it and finish
|
||||
|
||||
@@ -89,6 +89,7 @@ public class RecentsConfiguration {
|
||||
public int taskBarEnterAnimDuration;
|
||||
public int taskBarEnterAnimDelay;
|
||||
public int taskBarExitAnimDuration;
|
||||
public int taskBarDismissDozeDelaySeconds;
|
||||
|
||||
/** Nav bar scrim */
|
||||
public int navBarScrimEnterDuration;
|
||||
@@ -205,6 +206,8 @@ public class RecentsConfiguration {
|
||||
res.getInteger(R.integer.recents_animate_task_bar_enter_delay);
|
||||
taskBarExitAnimDuration =
|
||||
res.getInteger(R.integer.recents_animate_task_bar_exit_duration);
|
||||
taskBarDismissDozeDelaySeconds =
|
||||
res.getInteger(R.integer.recents_task_bar_dismiss_delay_seconds);
|
||||
|
||||
// Nav bar scrim
|
||||
navBarScrimEnterDuration =
|
||||
|
||||
@@ -307,6 +307,20 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
|
||||
}
|
||||
}
|
||||
|
||||
/** Notifies each task view of the user interaction. */
|
||||
public void onUserInteraction() {
|
||||
// Get the first stack view
|
||||
TaskStackView stackView = null;
|
||||
int childCount = getChildCount();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
View child = getChildAt(i);
|
||||
if (child instanceof TaskStackView) {
|
||||
stackView = (TaskStackView) child;
|
||||
stackView.onUserInteraction();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Focuses the next task in the first stack view */
|
||||
public void focusNextTask(boolean forward) {
|
||||
// Get the first stack view
|
||||
|
||||
@@ -105,7 +105,7 @@ class TaskBarView extends FrameLayout {
|
||||
/** Synchronizes this bar view's properties with the task's transform */
|
||||
void updateViewPropertiesToTaskTransform(TaskViewTransform animateFromTransform,
|
||||
TaskViewTransform toTransform, int duration) {
|
||||
if (duration > 0) {
|
||||
if (duration > 0 && (mDismissButton.getVisibility() == View.VISIBLE)) {
|
||||
if (animateFromTransform != null) {
|
||||
mDismissButton.setAlpha(animateFromTransform.dismissAlpha);
|
||||
}
|
||||
@@ -169,7 +169,7 @@ class TaskBarView extends FrameLayout {
|
||||
setTranslationY(-getMeasuredHeight());
|
||||
animate()
|
||||
.translationY(0)
|
||||
.setStartDelay(delay > -1 ? delay : mConfig.taskBarEnterAnimDelay)
|
||||
.setStartDelay(delay)
|
||||
.setInterpolator(mConfig.fastOutSlowInInterpolator)
|
||||
.setDuration(mConfig.taskBarEnterAnimDuration)
|
||||
.withLayer()
|
||||
@@ -178,6 +178,7 @@ class TaskBarView extends FrameLayout {
|
||||
|
||||
/** Animates this task bar as it exits recents */
|
||||
public void animateOnLaunchingTask(final Runnable r) {
|
||||
// Animate the task bar out of the first task view
|
||||
animate()
|
||||
.translationY(-getMeasuredHeight())
|
||||
.setStartDelay(0)
|
||||
@@ -193,6 +194,28 @@ class TaskBarView extends FrameLayout {
|
||||
.start();
|
||||
}
|
||||
|
||||
/** Animates this task bar if the user does not interact with the stack after a certain time. */
|
||||
public void animateOnNoUserInteraction() {
|
||||
mDismissButton.setVisibility(View.VISIBLE);
|
||||
mDismissButton.setAlpha(0f);
|
||||
mDismissButton.animate()
|
||||
.alpha(1f)
|
||||
.setStartDelay(0)
|
||||
.setInterpolator(mConfig.fastOutLinearInInterpolator)
|
||||
.setDuration(mConfig.taskBarEnterAnimDuration)
|
||||
.withLayer()
|
||||
.start();
|
||||
}
|
||||
|
||||
/** Mark this task view that the user does has not interacted with the stack after a certain time. */
|
||||
public void setOnNoUserInteraction() {
|
||||
if (mDismissButton.getVisibility() != View.VISIBLE) {
|
||||
mDismissButton.animate().cancel();
|
||||
mDismissButton.setVisibility(View.VISIBLE);
|
||||
mDismissButton.setAlpha(1f);
|
||||
}
|
||||
}
|
||||
|
||||
/** Enable the hw layers on this task view */
|
||||
void enableHwLayers() {
|
||||
mDismissButton.setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
||||
|
||||
@@ -38,6 +38,7 @@ import android.widget.OverScroller;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.recents.Console;
|
||||
import com.android.systemui.recents.Constants;
|
||||
import com.android.systemui.recents.DozeTrigger;
|
||||
import com.android.systemui.recents.RecentsConfiguration;
|
||||
import com.android.systemui.recents.RecentsPackageMonitor;
|
||||
import com.android.systemui.recents.RecentsTaskLoader;
|
||||
@@ -70,6 +71,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
TaskStackViewCallbacks mCb;
|
||||
ViewPool<TaskView, Task> mViewPool;
|
||||
ArrayList<TaskViewTransform> mTaskTransforms = new ArrayList<TaskViewTransform>();
|
||||
DozeTrigger mDozeTrigger;
|
||||
|
||||
// The various rects that define the stack view
|
||||
Rect mRect = new Rect();
|
||||
@@ -107,6 +109,17 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
mTouchHandler = new TaskStackViewTouchHandler(context, this);
|
||||
mViewPool = new ViewPool<TaskView, Task>(context, this);
|
||||
mInflater = LayoutInflater.from(context);
|
||||
mDozeTrigger = new DozeTrigger(mConfig.taskBarDismissDozeDelaySeconds, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Show the task bar dismiss buttons
|
||||
int childCount = getChildCount();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
TaskView tv = (TaskView) getChildAt(i);
|
||||
tv.animateOnNoUserInteraction();
|
||||
}
|
||||
}
|
||||
});
|
||||
mHwLayersTrigger = new ReferenceCountedTrigger(getContext(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -797,6 +810,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
// Mark that we have completely the first layout
|
||||
mAwaitingFirstLayout = false;
|
||||
|
||||
// Start dozing
|
||||
mDozeTrigger.startDozing();
|
||||
|
||||
// Prepare the first view for its enter animation
|
||||
int offsetTopAlign = -mTaskRect.top;
|
||||
int offscreenY = mRect.bottom - (mTaskRect.top - mRect.top);
|
||||
@@ -867,6 +883,15 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
return isTransformedTouchPointInView(x, y, child, null);
|
||||
}
|
||||
|
||||
/** Pokes the dozer on user interaction. */
|
||||
void onUserInteraction() {
|
||||
// If the dozer is not running, then either we have not yet laid out, or it has already
|
||||
// fallen asleep, so just let it rest.
|
||||
if (mDozeTrigger.isDozing()) {
|
||||
mDozeTrigger.poke();
|
||||
}
|
||||
}
|
||||
|
||||
/**** TaskStackCallbacks Implementation ****/
|
||||
|
||||
@Override
|
||||
@@ -1152,6 +1177,11 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
// but just in case, re-enable it here
|
||||
tv.setClipViewInStack(true);
|
||||
|
||||
// If the doze trigger has already fired, then update the state for this task view
|
||||
if (mDozeTrigger.hasTriggered()) {
|
||||
tv.setOnNoUserInteraction();
|
||||
}
|
||||
|
||||
// Add/attach the view to the hierarchy
|
||||
if (Console.Enabled) {
|
||||
Console.log(Constants.Log.ViewPool.PoolCallbacks, " [TaskStackView|insertIndex]",
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.recents.views;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
@@ -93,6 +94,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
mConfig = RecentsConfiguration.getInstance();
|
||||
setWillNotDraw(false);
|
||||
setDim(getDim());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -206,7 +208,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
|
||||
setScaleX(1f);
|
||||
setScaleY(1f);
|
||||
setAlpha(1f);
|
||||
mDim = 0;
|
||||
setDim(0);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@@ -251,6 +253,8 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
|
||||
if (isTaskViewFrontMost) {
|
||||
// Hide the front most task bar view so we can animate it in
|
||||
mBarView.prepareAnimateEnterRecents();
|
||||
// Set the dim to 0 so we can animate it in
|
||||
setDim(0);
|
||||
}
|
||||
|
||||
} else if (mConfig.launchedFromHome) {
|
||||
@@ -292,7 +296,13 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
|
||||
} else if (mConfig.launchedFromAppWithThumbnail) {
|
||||
if (ctx.isFrontMost) {
|
||||
// Animate the task bar of the first task view
|
||||
mBarView.animateOnEnterRecents(-1);
|
||||
mBarView.animateOnEnterRecents(mConfig.taskBarEnterAnimDelay);
|
||||
// Animate the dim into view as well
|
||||
ObjectAnimator anim = ObjectAnimator.ofInt(this, "dim", getDimOverlayFromScale());
|
||||
anim.setStartDelay(mConfig.taskBarEnterAnimDelay);
|
||||
anim.setDuration(mConfig.taskBarEnterAnimDuration);
|
||||
anim.setInterpolator(mConfig.fastOutLinearInInterpolator);
|
||||
anim.start();
|
||||
}
|
||||
|
||||
} else if (mConfig.launchedFromHome) {
|
||||
@@ -325,9 +335,27 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
|
||||
ctx.postAnimationTrigger.increment();
|
||||
}
|
||||
|
||||
/** Animates this task view if the user does not interact with the stack after a certain time. */
|
||||
public void animateOnNoUserInteraction() {
|
||||
mBarView.animateOnNoUserInteraction();
|
||||
}
|
||||
|
||||
/** Mark this task view that the user does has not interacted with the stack after a certain time. */
|
||||
public void setOnNoUserInteraction() {
|
||||
mBarView.setOnNoUserInteraction();
|
||||
}
|
||||
|
||||
/** Animates this task view as it exits recents */
|
||||
public void animateOnLaunchingTask(final Runnable r) {
|
||||
mBarView.animateOnLaunchingTask(r);
|
||||
|
||||
// Animate the dim
|
||||
if (mDim > 0) {
|
||||
ObjectAnimator anim = ObjectAnimator.ofInt(this, "dim", 0);
|
||||
anim.setDuration(mConfig.taskBarExitAnimDuration);
|
||||
anim.setInterpolator(mConfig.fastOutLinearInInterpolator);
|
||||
anim.start();
|
||||
}
|
||||
}
|
||||
|
||||
/** Animates the deletion of this task view */
|
||||
@@ -398,13 +426,29 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
|
||||
}
|
||||
}
|
||||
|
||||
/** Update the dim as a function of the scale of this view. */
|
||||
void updateDimOverlayFromScale() {
|
||||
/** Returns the current dim. */
|
||||
public void setDim(int dim) {
|
||||
mDim = dim;
|
||||
postInvalidateOnAnimation();
|
||||
}
|
||||
|
||||
/** Returns the current dim. */
|
||||
public int getDim() {
|
||||
return mDim;
|
||||
}
|
||||
|
||||
/** Compute the dim as a function of the scale of this view. */
|
||||
int getDimOverlayFromScale() {
|
||||
float minScale = Constants.Values.TaskStackView.StackPeekMinScale;
|
||||
float scaleRange = 1f - minScale;
|
||||
float dim = (1f - getScaleX()) / scaleRange;
|
||||
dim = mDimInterpolator.getInterpolation(Math.min(dim, 1f));
|
||||
mDim = Math.max(0, Math.min(mMaxDim, (int) (dim * 255)));
|
||||
return Math.max(0, Math.min(mMaxDim, (int) (dim * 255)));
|
||||
}
|
||||
|
||||
/** Update the dim as a function of the scale of this view. */
|
||||
void updateDimOverlayFromScale() {
|
||||
setDim(getDimOverlayFromScale());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user