Loading quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +7 −1 Original line number Diff line number Diff line Loading @@ -634,7 +634,10 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener boolean appTargetsAreTranslucent = areAllTargetsTranslucent(appTargets); RectF launcherIconBounds = new RectF(); FloatingIconView floatingView = FloatingIconView.getFloatingIconView(mLauncher, v, FloatingIconView floatingView = getFloatingIconView(mLauncher, v, mLauncher.getTaskbarUIController() == null ? null : mLauncher.getTaskbarUIController().findMatchingView(v), !appTargetsAreTranslucent, launcherIconBounds, true /* isOpening */); Rect crop = new Rect(); Matrix matrix = new Matrix(); Loading Loading @@ -1350,6 +1353,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener isTransluscent, fallbackBackgroundColor); } else if (launcherView != null) { floatingIconView = getFloatingIconView(mLauncher, launcherView, mLauncher.getTaskbarUIController() == null ? null : mLauncher.getTaskbarUIController().findMatchingView(launcherView), true /* hideOriginal */, targetRect, false /* isOpening */); } else { targetRect.set(getDefaultWindowTargetRect()); Loading quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java +28 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.launcher3.taskbar; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION; import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_APP; import android.content.Intent; Loading Loading @@ -282,4 +284,30 @@ public class TaskbarUIController { * No-op if the view is not yet open. */ public void launchSplitTasks(@NonNull View taskview, @NonNull GroupTask groupTask) { } /** * Returns the matching view (if any) in the taskbar. * @param view The view to match. */ public @Nullable View findMatchingView(View view) { if (!(view.getTag() instanceof ItemInfo)) { return null; } ItemInfo info = (ItemInfo) view.getTag(); if (info.container != CONTAINER_HOTSEAT && info.container != CONTAINER_HOTSEAT_PREDICTION) { return null; } // Taskbar has the same items as the hotseat and we can use screenId to find the match. int screenId = info.screenId; View[] views = mControllers.taskbarViewController.getIconViews(); for (int i = views.length - 1; i >= 0; --i) { if (views[i] != null && views[i].getTag() instanceof ItemInfo && ((ItemInfo) views[i].getTag()).screenId == screenId) { return views[i]; } } return null; } } quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java +3 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,9 @@ public class LauncherSwipeHandlerV2 extends private HomeAnimationFactory createIconHomeAnimationFactory(View workspaceView) { RectF iconLocation = new RectF(); FloatingIconView floatingIconView = getFloatingIconView(mActivity, workspaceView, mActivity.getTaskbarUIController() == null ? null : mActivity.getTaskbarUIController().findMatchingView(workspaceView), true /* hideOriginal */, iconLocation, false /* isOpening */); // We want the window alpha to be 0 once this threshold is met, so that the Loading src/com/android/launcher3/views/FloatingIconView.java +24 −9 Original line number Diff line number Diff line Loading @@ -95,6 +95,9 @@ public class FloatingIconView extends FrameLayout implements private ClipIconView mClipIconView; private @Nullable Drawable mBadge; // A view whose visibility should update in sync with mOriginalIcon. private @Nullable View mMatchVisibilityView; private View mOriginalIcon; private RectF mPositionOut; private Runnable mOnTargetChangeRunnable; Loading Loading @@ -386,7 +389,7 @@ public class FloatingIconView extends FrameLayout implements * Checks if the icon result is loaded. If true, we set the icon immediately. Else, we add a * callback to set the icon once the icon result is loaded. */ private void checkIconResult(View originalView) { private void checkIconResult() { CancellationSignal cancellationSignal = new CancellationSignal(); if (mIconLoadResult == null) { Loading @@ -399,7 +402,7 @@ public class FloatingIconView extends FrameLayout implements setIcon(mIconLoadResult.drawable, mIconLoadResult.badge, mIconLoadResult.btvDrawable, mIconLoadResult.iconOffset); setVisibility(VISIBLE); setIconAndDotVisible(originalView, false); updateViewsVisibility(false /* isVisible */); } else { mIconLoadResult.onIconLoaded = () -> { if (cancellationSignal.isCanceled()) { Loading @@ -410,7 +413,7 @@ public class FloatingIconView extends FrameLayout implements mIconLoadResult.btvDrawable, mIconLoadResult.iconOffset); setVisibility(VISIBLE); setIconAndDotVisible(originalView, false); updateViewsVisibility(false /* isVisible */); }; mLoadIconSignal = cancellationSignal; } Loading Loading @@ -481,9 +484,9 @@ public class FloatingIconView extends FrameLayout implements // No need to wait for icon load since we can display the BubbleTextView drawable. setVisibility(View.VISIBLE); } if (!mIsOpening && mOriginalIcon != null) { if (!mIsOpening) { // When closing an app, we want the item on the workspace to be invisible immediately setIconAndDotVisible(mOriginalIcon, false); updateViewsVisibility(false /* isVisible */); } } Loading Loading @@ -562,13 +565,14 @@ public class FloatingIconView extends FrameLayout implements /** * Creates a floating icon view for {@param originalView}. * @param originalView The view to copy * @param secondView A view whose visibility should update in sync with originalView. * @param hideOriginal If true, it will hide {@param originalView} while this view is visible. * Else, we will not draw anything in this view. * @param positionOut Rect that will hold the size and position of v. * @param isOpening True if this view replaces the icon for app open animation. */ public static FloatingIconView getFloatingIconView(Launcher launcher, View originalView, boolean hideOriginal, RectF positionOut, boolean isOpening) { @Nullable View secondView, boolean hideOriginal, RectF positionOut, boolean isOpening) { final DragLayer dragLayer = launcher.getDragLayer(); ViewGroup parent = (ViewGroup) dragLayer.getParent(); FloatingIconView view = launcher.getViewCache().getView(R.layout.floating_icon_view, Loading @@ -578,6 +582,7 @@ public class FloatingIconView extends FrameLayout implements // Init properties before getting the drawable. view.mIsOpening = isOpening; view.mOriginalIcon = originalView; view.mMatchVisibilityView = secondView; view.mPositionOut = positionOut; // Get the drawable on the background thread Loading @@ -597,7 +602,8 @@ public class FloatingIconView extends FrameLayout implements view.matchPositionOf(launcher, originalView, isOpening, positionOut); // We need to add it to the overlay, but keep it invisible until animation starts.. setIconAndDotVisible(view, false); view.setVisibility(View.INVISIBLE); parent.addView(view); dragLayer.addView(view.mListenerView); view.mListenerView.setListener(view::fastFinish); Loading @@ -606,7 +612,7 @@ public class FloatingIconView extends FrameLayout implements view.mEndRunnable = null; if (hideOriginal) { setIconAndDotVisible(originalView, true); view.updateViewsVisibility(true /* isVisible */); view.finish(dragLayer); } else { view.finish(dragLayer); Loading @@ -617,12 +623,21 @@ public class FloatingIconView extends FrameLayout implements // Must be called after the fastFinish listener and end runnable is created so that // the icon is not left in a hidden state. if (shouldLoadIcon) { view.checkIconResult(originalView); view.checkIconResult(); } return view; } private void updateViewsVisibility(boolean isVisible) { if (mOriginalIcon != null) { setIconAndDotVisible(mOriginalIcon, isVisible); } if (mMatchVisibilityView != null) { setIconAndDotVisible(mMatchVisibilityView, isVisible); } } private void finish(DragLayer dragLayer) { ((ViewGroup) dragLayer.getParent()).removeView(this); dragLayer.removeView(mListenerView); Loading Loading
quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +7 −1 Original line number Diff line number Diff line Loading @@ -634,7 +634,10 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener boolean appTargetsAreTranslucent = areAllTargetsTranslucent(appTargets); RectF launcherIconBounds = new RectF(); FloatingIconView floatingView = FloatingIconView.getFloatingIconView(mLauncher, v, FloatingIconView floatingView = getFloatingIconView(mLauncher, v, mLauncher.getTaskbarUIController() == null ? null : mLauncher.getTaskbarUIController().findMatchingView(v), !appTargetsAreTranslucent, launcherIconBounds, true /* isOpening */); Rect crop = new Rect(); Matrix matrix = new Matrix(); Loading Loading @@ -1350,6 +1353,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener isTransluscent, fallbackBackgroundColor); } else if (launcherView != null) { floatingIconView = getFloatingIconView(mLauncher, launcherView, mLauncher.getTaskbarUIController() == null ? null : mLauncher.getTaskbarUIController().findMatchingView(launcherView), true /* hideOriginal */, targetRect, false /* isOpening */); } else { targetRect.set(getDefaultWindowTargetRect()); Loading
quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java +28 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,8 @@ package com.android.launcher3.taskbar; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION; import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_APP; import android.content.Intent; Loading Loading @@ -282,4 +284,30 @@ public class TaskbarUIController { * No-op if the view is not yet open. */ public void launchSplitTasks(@NonNull View taskview, @NonNull GroupTask groupTask) { } /** * Returns the matching view (if any) in the taskbar. * @param view The view to match. */ public @Nullable View findMatchingView(View view) { if (!(view.getTag() instanceof ItemInfo)) { return null; } ItemInfo info = (ItemInfo) view.getTag(); if (info.container != CONTAINER_HOTSEAT && info.container != CONTAINER_HOTSEAT_PREDICTION) { return null; } // Taskbar has the same items as the hotseat and we can use screenId to find the match. int screenId = info.screenId; View[] views = mControllers.taskbarViewController.getIconViews(); for (int i = views.length - 1; i >= 0; --i) { if (views[i] != null && views[i].getTag() instanceof ItemInfo && ((ItemInfo) views[i].getTag()).screenId == screenId) { return views[i]; } } return null; } }
quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java +3 −0 Original line number Diff line number Diff line Loading @@ -105,6 +105,9 @@ public class LauncherSwipeHandlerV2 extends private HomeAnimationFactory createIconHomeAnimationFactory(View workspaceView) { RectF iconLocation = new RectF(); FloatingIconView floatingIconView = getFloatingIconView(mActivity, workspaceView, mActivity.getTaskbarUIController() == null ? null : mActivity.getTaskbarUIController().findMatchingView(workspaceView), true /* hideOriginal */, iconLocation, false /* isOpening */); // We want the window alpha to be 0 once this threshold is met, so that the Loading
src/com/android/launcher3/views/FloatingIconView.java +24 −9 Original line number Diff line number Diff line Loading @@ -95,6 +95,9 @@ public class FloatingIconView extends FrameLayout implements private ClipIconView mClipIconView; private @Nullable Drawable mBadge; // A view whose visibility should update in sync with mOriginalIcon. private @Nullable View mMatchVisibilityView; private View mOriginalIcon; private RectF mPositionOut; private Runnable mOnTargetChangeRunnable; Loading Loading @@ -386,7 +389,7 @@ public class FloatingIconView extends FrameLayout implements * Checks if the icon result is loaded. If true, we set the icon immediately. Else, we add a * callback to set the icon once the icon result is loaded. */ private void checkIconResult(View originalView) { private void checkIconResult() { CancellationSignal cancellationSignal = new CancellationSignal(); if (mIconLoadResult == null) { Loading @@ -399,7 +402,7 @@ public class FloatingIconView extends FrameLayout implements setIcon(mIconLoadResult.drawable, mIconLoadResult.badge, mIconLoadResult.btvDrawable, mIconLoadResult.iconOffset); setVisibility(VISIBLE); setIconAndDotVisible(originalView, false); updateViewsVisibility(false /* isVisible */); } else { mIconLoadResult.onIconLoaded = () -> { if (cancellationSignal.isCanceled()) { Loading @@ -410,7 +413,7 @@ public class FloatingIconView extends FrameLayout implements mIconLoadResult.btvDrawable, mIconLoadResult.iconOffset); setVisibility(VISIBLE); setIconAndDotVisible(originalView, false); updateViewsVisibility(false /* isVisible */); }; mLoadIconSignal = cancellationSignal; } Loading Loading @@ -481,9 +484,9 @@ public class FloatingIconView extends FrameLayout implements // No need to wait for icon load since we can display the BubbleTextView drawable. setVisibility(View.VISIBLE); } if (!mIsOpening && mOriginalIcon != null) { if (!mIsOpening) { // When closing an app, we want the item on the workspace to be invisible immediately setIconAndDotVisible(mOriginalIcon, false); updateViewsVisibility(false /* isVisible */); } } Loading Loading @@ -562,13 +565,14 @@ public class FloatingIconView extends FrameLayout implements /** * Creates a floating icon view for {@param originalView}. * @param originalView The view to copy * @param secondView A view whose visibility should update in sync with originalView. * @param hideOriginal If true, it will hide {@param originalView} while this view is visible. * Else, we will not draw anything in this view. * @param positionOut Rect that will hold the size and position of v. * @param isOpening True if this view replaces the icon for app open animation. */ public static FloatingIconView getFloatingIconView(Launcher launcher, View originalView, boolean hideOriginal, RectF positionOut, boolean isOpening) { @Nullable View secondView, boolean hideOriginal, RectF positionOut, boolean isOpening) { final DragLayer dragLayer = launcher.getDragLayer(); ViewGroup parent = (ViewGroup) dragLayer.getParent(); FloatingIconView view = launcher.getViewCache().getView(R.layout.floating_icon_view, Loading @@ -578,6 +582,7 @@ public class FloatingIconView extends FrameLayout implements // Init properties before getting the drawable. view.mIsOpening = isOpening; view.mOriginalIcon = originalView; view.mMatchVisibilityView = secondView; view.mPositionOut = positionOut; // Get the drawable on the background thread Loading @@ -597,7 +602,8 @@ public class FloatingIconView extends FrameLayout implements view.matchPositionOf(launcher, originalView, isOpening, positionOut); // We need to add it to the overlay, but keep it invisible until animation starts.. setIconAndDotVisible(view, false); view.setVisibility(View.INVISIBLE); parent.addView(view); dragLayer.addView(view.mListenerView); view.mListenerView.setListener(view::fastFinish); Loading @@ -606,7 +612,7 @@ public class FloatingIconView extends FrameLayout implements view.mEndRunnable = null; if (hideOriginal) { setIconAndDotVisible(originalView, true); view.updateViewsVisibility(true /* isVisible */); view.finish(dragLayer); } else { view.finish(dragLayer); Loading @@ -617,12 +623,21 @@ public class FloatingIconView extends FrameLayout implements // Must be called after the fastFinish listener and end runnable is created so that // the icon is not left in a hidden state. if (shouldLoadIcon) { view.checkIconResult(originalView); view.checkIconResult(); } return view; } private void updateViewsVisibility(boolean isVisible) { if (mOriginalIcon != null) { setIconAndDotVisible(mOriginalIcon, isVisible); } if (mMatchVisibilityView != null) { setIconAndDotVisible(mMatchVisibilityView, isVisible); } } private void finish(DragLayer dragLayer) { ((ViewGroup) dragLayer.getParent()).removeView(this); dragLayer.removeView(mListenerView); Loading