Updating taskbar icon alignment state
Icon alignment is only tied to Launcher paused/resumed state Creating two separate states for this: 1) Launcher paused/resumed 2) Active gesture interaction (live-titles can affect paused state) Removing state handler dependency on taskbar visibility Bug: 190170303 Bug: 187353581 Bug: 187919439 Test: Manual Change-Id: Ia97cdf43cec1d9213f5dc2af8d66258b34c57514
This commit is contained in:
parent
e7cf240e0c
commit
5cf86b263e
|
@ -15,27 +15,29 @@
|
|||
*/
|
||||
package com.android.launcher3.taskbar;
|
||||
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.LauncherState.HOTSEAT_ICONS;
|
||||
import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_HOME;
|
||||
import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_LAUNCHER_STATE;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.graphics.Rect;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.BaseQuickstepLauncher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.QuickstepTransitionManager;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.AnimatorListeners;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.util.MultiValueAlpha;
|
||||
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
|
||||
import com.android.quickstep.AnimatedFloat;
|
||||
import com.android.quickstep.RecentsAnimationCallbacks;
|
||||
import com.android.quickstep.RecentsAnimationCallbacks.RecentsAnimationListener;
|
||||
import com.android.quickstep.RecentsAnimationController;
|
||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -51,12 +53,19 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
|
|||
final TaskbarDragLayer mTaskbarDragLayer;
|
||||
final TaskbarView mTaskbarView;
|
||||
|
||||
private final AnimatedFloat mIconAlignmentForResumedState =
|
||||
new AnimatedFloat(this::onIconAlignmentRatioChanged);
|
||||
private final AnimatedFloat mIconAlignmentForGestureState =
|
||||
new AnimatedFloat(this::onIconAlignmentRatioChanged);
|
||||
|
||||
private AnimatedFloat mTaskbarBackgroundAlpha;
|
||||
private AlphaProperty mIconAlphaForHome;
|
||||
private @Nullable Animator mAnimator;
|
||||
private boolean mIsAnimatingToLauncher;
|
||||
private TaskbarKeyguardController mKeyguardController;
|
||||
|
||||
private LauncherState mTargetStateOverride = null;
|
||||
private TaskbarControllers mControllers;
|
||||
|
||||
public LauncherTaskbarUIController(
|
||||
BaseQuickstepLauncher launcher, TaskbarActivityContext context) {
|
||||
mContext = context;
|
||||
|
@ -67,7 +76,6 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
|
|||
mTaskbarStateHandler = mLauncher.getTaskbarStateHandler();
|
||||
mHotseatController = new TaskbarHotseatController(
|
||||
mLauncher, mTaskbarView::updateHotseatItems);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -77,21 +85,17 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
|
|||
MultiValueAlpha taskbarIconAlpha = taskbarControllers.taskbarViewController
|
||||
.getTaskbarIconAlpha();
|
||||
mIconAlphaForHome = taskbarIconAlpha.getProperty(ALPHA_INDEX_HOME);
|
||||
mTaskbarStateHandler.setAnimationController(taskbarIconAlpha.getProperty(
|
||||
ALPHA_INDEX_LAUNCHER_STATE));
|
||||
mControllers = taskbarControllers;
|
||||
|
||||
mHotseatController.init();
|
||||
setTaskbarViewVisible(!mLauncher.hasBeenResumed());
|
||||
mLauncher.setTaskbarUIController(this);
|
||||
mKeyguardController = taskbarControllers.taskbarKeyguardController;
|
||||
onLauncherResumedOrPaused(mLauncher.hasBeenResumed());
|
||||
mIconAlignmentForResumedState.finishAnimation();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
if (mAnimator != null) {
|
||||
// End this first, in case it relies on properties that are about to be cleaned up.
|
||||
mAnimator.end();
|
||||
}
|
||||
mTaskbarStateHandler.setAnimationController(null);
|
||||
mHotseatController.cleanup();
|
||||
setTaskbarViewVisible(true);
|
||||
mLauncher.getHotseat().setIconsAlpha(1f);
|
||||
|
@ -100,7 +104,7 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
|
|||
|
||||
@Override
|
||||
protected boolean isTaskbarTouchable() {
|
||||
return !mIsAnimatingToLauncher;
|
||||
return !mIsAnimatingToLauncher && mTargetStateOverride == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -128,63 +132,82 @@ public class LauncherTaskbarUIController extends TaskbarUIController {
|
|||
}
|
||||
}
|
||||
|
||||
long duration = QuickstepTransitionManager.CONTENT_ALPHA_DURATION;
|
||||
if (mAnimator != null) {
|
||||
mAnimator.cancel();
|
||||
}
|
||||
if (isResumed) {
|
||||
mAnimator = createAnimToLauncher(mLauncher.getStateManager().getState(), duration);
|
||||
} else {
|
||||
mAnimator = createAnimToApp(duration);
|
||||
}
|
||||
mAnimator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mAnimator = null;
|
||||
}
|
||||
});
|
||||
mAnimator.start();
|
||||
ObjectAnimator anim = mIconAlignmentForResumedState.animateToValue(
|
||||
getCurrentIconAlignmentRatio(), isResumed ? 1 : 0)
|
||||
.setDuration(QuickstepTransitionManager.CONTENT_ALPHA_DURATION);
|
||||
|
||||
anim.addListener(AnimatorListeners.forEndCallback(() -> mIsAnimatingToLauncher = false));
|
||||
anim.start();
|
||||
mIsAnimatingToLauncher = isResumed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Taskbar animation when going from an app to Launcher.
|
||||
* Create Taskbar animation when going from an app to Launcher as part of recents transition.
|
||||
* @param toState If known, the state we will end up in when reaching Launcher.
|
||||
* TODO: Move this and createAnimToApp to TaskbarStateHandler using the BACKGROUND state
|
||||
* @param callbacks callbacks to track the recents animation lifecycle. The state change is
|
||||
* automatically reset once the recents animation finishes
|
||||
*/
|
||||
public Animator createAnimToLauncher(@NonNull LauncherState toState, long duration) {
|
||||
PendingAnimation anim = new PendingAnimation(duration);
|
||||
mTaskbarStateHandler.setState(toState, anim);
|
||||
|
||||
anim.setFloat(mTaskbarBackgroundAlpha, AnimatedFloat.VALUE, 0, LINEAR);
|
||||
mTaskbarView.alignIconsWithLauncher(mLauncher.getDeviceProfile(), anim);
|
||||
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
mIsAnimatingToLauncher = true;
|
||||
}
|
||||
|
||||
public Animator createAnimToLauncher(@NonNull LauncherState toState,
|
||||
@NonNull RecentsAnimationCallbacks callbacks,
|
||||
long duration) {
|
||||
ObjectAnimator animator = mIconAlignmentForGestureState
|
||||
.animateToValue(mIconAlignmentForGestureState.value, 1)
|
||||
.setDuration(duration);
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mIsAnimatingToLauncher = false;
|
||||
setTaskbarViewVisible(false);
|
||||
mTargetStateOverride = null;
|
||||
}
|
||||
});
|
||||
|
||||
return anim.buildAnim();
|
||||
}
|
||||
|
||||
private Animator createAnimToApp(long duration) {
|
||||
PendingAnimation anim = new PendingAnimation(duration);
|
||||
anim.setFloat(mTaskbarBackgroundAlpha, AnimatedFloat.VALUE, 1, LINEAR);
|
||||
anim.addListener(AnimatorListeners.forEndCallback(mTaskbarView.resetIconPosition(anim)));
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
setTaskbarViewVisible(true);
|
||||
mTargetStateOverride = toState;
|
||||
}
|
||||
});
|
||||
return anim.buildAnim();
|
||||
callbacks.addListener(new RecentsAnimationListener() {
|
||||
@Override
|
||||
public void onRecentsAnimationCanceled(ThumbnailData thumbnailData) {
|
||||
endGestureStateOverride();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationFinished(RecentsAnimationController controller) {
|
||||
endGestureStateOverride();
|
||||
}
|
||||
|
||||
private void endGestureStateOverride() {
|
||||
callbacks.removeListener(this);
|
||||
mIconAlignmentForGestureState
|
||||
.animateToValue(mIconAlignmentForGestureState.value, 0)
|
||||
.start();
|
||||
}
|
||||
});
|
||||
return animator;
|
||||
}
|
||||
|
||||
private float getCurrentIconAlignmentRatio() {
|
||||
return Math.max(mIconAlignmentForResumedState.value, mIconAlignmentForGestureState.value);
|
||||
}
|
||||
|
||||
private void onIconAlignmentRatioChanged() {
|
||||
if (mControllers == null) {
|
||||
return;
|
||||
}
|
||||
float alignment = getCurrentIconAlignmentRatio();
|
||||
mControllers.taskbarViewController.setLauncherIconAlignment(
|
||||
alignment, mLauncher.getDeviceProfile());
|
||||
|
||||
mTaskbarBackgroundAlpha.updateValue(1 - alignment);
|
||||
|
||||
LauncherState state = mTargetStateOverride != null ? mTargetStateOverride
|
||||
: mLauncher.getStateManager().getState();
|
||||
if ((state.getVisibleElements(mLauncher) & HOTSEAT_ICONS) != 0) {
|
||||
// If the hotseat icons are visible, then switch taskbar in last frame
|
||||
setTaskbarViewVisible(alignment < 1);
|
||||
} else {
|
||||
mLauncher.getHotseat().setIconsAlpha(1);
|
||||
mIconAlphaForHome.setValue(1 - alignment);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,7 +17,6 @@ package com.android.launcher3.taskbar;
|
|||
|
||||
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
|
||||
|
||||
import static com.android.systemui.shared.system.WindowManagerWrapper.ITYPE_BOTTOM_TAPPABLE_ELEMENT;
|
||||
|
@ -93,6 +92,7 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
|
|||
private final ViewCache mViewCache = new ViewCache();
|
||||
|
||||
private final boolean mIsSafeModeEnabled;
|
||||
private boolean mIsDestroyed = false;
|
||||
|
||||
public TaskbarActivityContext(Context windowContext, DeviceProfile dp,
|
||||
TaskbarNavButtonController buttonController) {
|
||||
|
@ -208,6 +208,7 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
|
|||
* Called when this instance of taskbar is no longer needed
|
||||
*/
|
||||
public void onDestroy() {
|
||||
mIsDestroyed = true;
|
||||
setUIController(TaskbarUIController.DEFAULT);
|
||||
mControllers.onDestroy();
|
||||
mWindowManager.removeViewImmediate(mDragLayer);
|
||||
|
@ -252,7 +253,7 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
|
|||
* Updates the TaskbarContainer height (pass deviceProfile.taskbarSize to reset).
|
||||
*/
|
||||
public void setTaskbarWindowHeight(int height) {
|
||||
if (mWindowLayoutParams.height == height) {
|
||||
if (mWindowLayoutParams.height == height || mIsDestroyed) {
|
||||
return;
|
||||
}
|
||||
if (height != MATCH_PARENT) {
|
||||
|
|
|
@ -18,45 +18,33 @@ package com.android.launcher3.taskbar;
|
|||
import static com.android.launcher3.LauncherState.TASKBAR;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.BaseQuickstepLauncher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.anim.PropertySetter;
|
||||
import com.android.launcher3.statemanager.StateManager;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.launcher3.util.MultiValueAlpha;
|
||||
import com.android.quickstep.AnimatedFloat;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
|
||||
/**
|
||||
* StateHandler to animate Taskbar according to Launcher's state machine. Does nothing if Taskbar
|
||||
* isn't present (i.e. {@link #setAnimationController} is never called).
|
||||
* StateHandler to animate Taskbar according to Launcher's state machine.
|
||||
*/
|
||||
public class TaskbarStateHandler implements StateManager.StateHandler<LauncherState> {
|
||||
|
||||
private final BaseQuickstepLauncher mLauncher;
|
||||
|
||||
// Contains Taskbar-related properties we should aniamte. If null, don't do anything.
|
||||
private @Nullable MultiValueAlpha.AlphaProperty mTaskbarAlpha = null;
|
||||
|
||||
private AnimatedFloat mNavbarButtonAlpha = new AnimatedFloat(this::updateNavbarButtonAlpha);
|
||||
|
||||
public TaskbarStateHandler(BaseQuickstepLauncher launcher) {
|
||||
mLauncher = launcher;
|
||||
}
|
||||
|
||||
public void setAnimationController(MultiValueAlpha.AlphaProperty taskbarAlpha) {
|
||||
mTaskbarAlpha = taskbarAlpha;
|
||||
// Reapply state.
|
||||
setState(mLauncher.getStateManager().getState());
|
||||
updateNavbarButtonAlpha();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setState(LauncherState state) {
|
||||
setState(state, PropertySetter.NO_ANIM_PROPERTY_SETTER);
|
||||
// Force update the alpha in case it was not initialized properly
|
||||
updateNavbarButtonAlpha();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -69,12 +57,7 @@ public class TaskbarStateHandler implements StateManager.StateHandler<LauncherSt
|
|||
* Sets the provided state
|
||||
*/
|
||||
public void setState(LauncherState toState, PropertySetter setter) {
|
||||
if (mTaskbarAlpha == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isTaskbarVisible = (toState.getVisibleElements(mLauncher) & TASKBAR) != 0;
|
||||
setter.setFloat(mTaskbarAlpha, MultiValueAlpha.VALUE, isTaskbarVisible ? 1f : 0f, LINEAR);
|
||||
// Make the nav bar visible in states that taskbar isn't visible.
|
||||
// TODO: We should draw our own handle instead of showing the nav bar.
|
||||
float navbarButtonAlpha = isTaskbarVisible ? 0f : 1f;
|
||||
|
|
|
@ -15,11 +15,6 @@
|
|||
*/
|
||||
package com.android.launcher3.taskbar;
|
||||
|
||||
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
||||
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
|
||||
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Canvas;
|
||||
|
@ -34,10 +29,8 @@ import androidx.annotation.NonNull;
|
|||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.BubbleTextView;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Insettable;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.PropertySetter;
|
||||
import com.android.launcher3.folder.FolderIcon;
|
||||
import com.android.launcher3.model.data.FolderInfo;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
|
@ -105,51 +98,6 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
|
|||
mIconLongClickListener = mControllerCallbacks.getOnLongClickListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* Aligns the icons in the taskbar to that of Launcher.
|
||||
*/
|
||||
public void alignIconsWithLauncher(DeviceProfile launcherDp, PropertySetter setter) {
|
||||
Rect hotseatPadding = launcherDp.getHotseatLayoutPadding(getContext());
|
||||
float scaleUp = ((float) launcherDp.iconSizePx)
|
||||
/ mActivityContext.getDeviceProfile().iconSizePx;
|
||||
int hotseatCellSize =
|
||||
(launcherDp.availableWidthPx - hotseatPadding.left - hotseatPadding.right)
|
||||
/ launcherDp.numShownHotseatIcons;
|
||||
|
||||
int offsetY = launcherDp.getTaskbarOffsetY();
|
||||
setter.setFloat(this, VIEW_TRANSLATE_Y, -offsetY, LINEAR);
|
||||
mActivityContext.setTaskbarWindowHeight(
|
||||
mActivityContext.getDeviceProfile().taskbarSize + offsetY);
|
||||
|
||||
int count = getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
View child = getChildAt(i);
|
||||
ItemInfo info = (ItemInfo) child.getTag();
|
||||
setter.setFloat(child, SCALE_PROPERTY, scaleUp, LINEAR);
|
||||
|
||||
float childCenter = (child.getLeft() + child.getRight()) / 2;
|
||||
float hotseatIconCenter = hotseatPadding.left + hotseatCellSize * info.screenId
|
||||
+ hotseatCellSize / 2;
|
||||
setter.setFloat(child, VIEW_TRANSLATE_X, hotseatIconCenter - childCenter, LINEAR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Aligns the icons in the taskbar to that of Launcher.
|
||||
* @return a callback to be executed at the end of the setter
|
||||
*/
|
||||
public Runnable resetIconPosition(PropertySetter setter) {
|
||||
int count = getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
View child = getChildAt(i);
|
||||
setter.setFloat(child, SCALE_PROPERTY, 1, LINEAR);
|
||||
setter.setFloat(child, VIEW_TRANSLATE_X, 0, LINEAR);
|
||||
}
|
||||
setter.setFloat(this, VIEW_TRANSLATE_Y, 0, LINEAR);
|
||||
return () -> mActivityContext.setTaskbarWindowHeight(
|
||||
mActivityContext.getDeviceProfile().taskbarSize);
|
||||
}
|
||||
|
||||
private void removeAndRecycle(View view) {
|
||||
removeView(view);
|
||||
view.setOnClickListener(null);
|
||||
|
@ -195,6 +143,7 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
|
|||
// so if the info changes we need to reinflate. This should only happen if a new
|
||||
// folder is dragged to the position that another folder previously existed.
|
||||
removeAndRecycle(hotseatView);
|
||||
hotseatView = null;
|
||||
} else {
|
||||
// View found
|
||||
break;
|
||||
|
|
|
@ -15,19 +15,29 @@
|
|||
*/
|
||||
package com.android.launcher3.taskbar;
|
||||
|
||||
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
|
||||
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X;
|
||||
import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.util.MultiValueAlpha;
|
||||
|
||||
/**
|
||||
* Handles properties/data collection, then passes the results to TaskbarView to render.
|
||||
*/
|
||||
public class TaskbarViewController {
|
||||
private static final Runnable NO_OP = () -> { };
|
||||
|
||||
public static final int ALPHA_INDEX_HOME = 0;
|
||||
public static final int ALPHA_INDEX_LAUNCHER_STATE = 1;
|
||||
public static final int ALPHA_INDEX_IME = 2;
|
||||
public static final int ALPHA_INDEX_KEYGUARD = 3;
|
||||
public static final int ALPHA_INDEX_IME = 1;
|
||||
public static final int ALPHA_INDEX_KEYGUARD = 2;
|
||||
|
||||
private final TaskbarActivityContext mActivity;
|
||||
private final TaskbarView mTaskbarView;
|
||||
|
@ -36,10 +46,15 @@ public class TaskbarViewController {
|
|||
// Initialized in init.
|
||||
private TaskbarControllers mControllers;
|
||||
|
||||
// Animation to align icons with Launcher, created lazily. This allows the controller to be
|
||||
// active only during the animation and does not need to worry about layout changes.
|
||||
private AnimatorPlaybackController mIconAlignControllerLazy = null;
|
||||
private Runnable mOnControllerPreCreateCallback = NO_OP;
|
||||
|
||||
public TaskbarViewController(TaskbarActivityContext activity, TaskbarView taskbarView) {
|
||||
mActivity = activity;
|
||||
mTaskbarView = taskbarView;
|
||||
mTaskbarIconAlpha = new MultiValueAlpha(mTaskbarView, 4);
|
||||
mTaskbarIconAlpha = new MultiValueAlpha(mTaskbarView, 3);
|
||||
mTaskbarIconAlpha.setUpdateVisibility(true);
|
||||
}
|
||||
|
||||
|
@ -71,6 +86,60 @@ public class TaskbarViewController {
|
|||
mTaskbarView.setClickAndLongClickListenersForIcon(icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the taskbar icon alignment relative to Launcher hotseat icons
|
||||
* @param alignmentRatio [0, 1]
|
||||
* 0 => not aligned
|
||||
* 1 => fully aligned
|
||||
*/
|
||||
public void setLauncherIconAlignment(float alignmentRatio, DeviceProfile launcherDp) {
|
||||
if (mIconAlignControllerLazy == null) {
|
||||
mIconAlignControllerLazy = createIconAlignmentController(launcherDp);
|
||||
}
|
||||
mIconAlignControllerLazy.setPlayFraction(alignmentRatio);
|
||||
if (alignmentRatio <= 0 || alignmentRatio >= 1) {
|
||||
// Cleanup lazy controller so that it is created again in next animation
|
||||
mIconAlignControllerLazy = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an animation for aligning the taskbar icons with the provided Launcher device profile
|
||||
*/
|
||||
private AnimatorPlaybackController createIconAlignmentController(DeviceProfile launcherDp) {
|
||||
mOnControllerPreCreateCallback.run();
|
||||
PendingAnimation setter = new PendingAnimation(100);
|
||||
Rect hotseatPadding = launcherDp.getHotseatLayoutPadding(mActivity);
|
||||
float scaleUp = ((float) launcherDp.iconSizePx) / mActivity.getDeviceProfile().iconSizePx;
|
||||
int hotseatCellSize =
|
||||
(launcherDp.availableWidthPx - hotseatPadding.left - hotseatPadding.right)
|
||||
/ launcherDp.numShownHotseatIcons;
|
||||
|
||||
int offsetY = launcherDp.getTaskbarOffsetY();
|
||||
setter.setFloat(mTaskbarView, VIEW_TRANSLATE_Y, -offsetY, LINEAR);
|
||||
|
||||
int collapsedHeight = mActivity.getDeviceProfile().taskbarSize;
|
||||
int expandedHeight = collapsedHeight + offsetY;
|
||||
setter.addOnFrameListener(anim -> mActivity.setTaskbarWindowHeight(
|
||||
anim.getAnimatedFraction() > 0 ? expandedHeight : collapsedHeight));
|
||||
|
||||
int count = mTaskbarView.getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
View child = mTaskbarView.getChildAt(i);
|
||||
ItemInfo info = (ItemInfo) child.getTag();
|
||||
setter.setFloat(child, SCALE_PROPERTY, scaleUp, LINEAR);
|
||||
|
||||
float childCenter = (child.getLeft() + child.getRight()) / 2;
|
||||
float hotseatIconCenter = hotseatPadding.left + hotseatCellSize * info.screenId
|
||||
+ hotseatCellSize / 2;
|
||||
setter.setFloat(child, VIEW_TRANSLATE_X, hotseatIconCenter - childCenter, LINEAR);
|
||||
}
|
||||
|
||||
AnimatorPlaybackController controller = setter.createPlaybackController();
|
||||
mOnControllerPreCreateCallback = () -> controller.setPlayFraction(0);
|
||||
return controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callbacks for {@link TaskbarView} to interact with its controller.
|
||||
*/
|
||||
|
|
|
@ -1107,7 +1107,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
|||
mActivityRestartListener);
|
||||
|
||||
mParallelRunningAnim = mActivityInterface.getParallelAnimationToLauncher(
|
||||
mGestureState.getEndTarget(), duration);
|
||||
mGestureState.getEndTarget(), duration,
|
||||
mTaskAnimationManager.getCurrentCallbacks());
|
||||
if (mParallelRunningAnim != null) {
|
||||
mParallelRunningAnim.start();
|
||||
}
|
||||
|
|
|
@ -346,7 +346,8 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
|||
* an optional additional animation with the same duration.
|
||||
*/
|
||||
public @Nullable Animator getParallelAnimationToLauncher(
|
||||
GestureState.GestureEndTarget endTarget, long duration) {
|
||||
GestureState.GestureEndTarget endTarget, long duration,
|
||||
RecentsAnimationCallbacks callbacks) {
|
||||
if (endTarget == RECENTS) {
|
||||
ACTIVITY_TYPE activity = getCreatedActivity();
|
||||
if (activity == null) {
|
||||
|
|
|
@ -284,14 +284,15 @@ public final class LauncherActivityInterface extends
|
|||
|
||||
@Override
|
||||
public @Nullable Animator getParallelAnimationToLauncher(GestureEndTarget endTarget,
|
||||
long duration) {
|
||||
long duration, RecentsAnimationCallbacks callbacks) {
|
||||
LauncherTaskbarUIController uiController = getTaskbarController();
|
||||
Animator superAnimator = super.getParallelAnimationToLauncher(endTarget, duration);
|
||||
if (uiController == null) {
|
||||
Animator superAnimator = super.getParallelAnimationToLauncher(
|
||||
endTarget, duration, callbacks);
|
||||
if (uiController == null || callbacks == null) {
|
||||
return superAnimator;
|
||||
}
|
||||
LauncherState toState = stateFromGestureEndTarget(endTarget);
|
||||
Animator taskbarAnimator = uiController.createAnimToLauncher(toState, duration);
|
||||
Animator taskbarAnimator = uiController.createAnimToLauncher(toState, callbacks, duration);
|
||||
if (superAnimator == null) {
|
||||
return taskbarAnimator;
|
||||
} else {
|
||||
|
|
|
@ -28,6 +28,7 @@ import android.os.Bundle;
|
|||
import android.os.SystemProperties;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.UiThread;
|
||||
|
||||
import com.android.launcher3.Utilities;
|
||||
|
@ -261,6 +262,11 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn
|
|||
mLastAppearedTaskTarget = null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public RecentsAnimationCallbacks getCurrentCallbacks() {
|
||||
return mCallbacks;
|
||||
}
|
||||
|
||||
public void dump() {
|
||||
// TODO
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue