diff --git a/quickstep/recents_ui_overrides/res/layout/proactive_hints_container.xml b/quickstep/recents_ui_overrides/res/layout/proactive_hints_container.xml new file mode 100644 index 0000000000..be3f17acd8 --- /dev/null +++ b/quickstep/recents_ui_overrides/res/layout/proactive_hints_container.xml @@ -0,0 +1,7 @@ + + \ No newline at end of file diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java index 11a1885d1a..c3a7698874 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java @@ -31,6 +31,7 @@ import com.android.launcher3.LauncherState; import com.android.launcher3.LauncherStateManager.AnimationConfig; import com.android.launcher3.anim.AnimatorSetBuilder; import com.android.launcher3.anim.PropertySetter; +import com.android.quickstep.hints.ProactiveHintsContainer; import com.android.quickstep.views.ClearAllButton; import com.android.quickstep.views.LauncherRecentsView; import com.android.quickstep.views.RecentsView; @@ -53,6 +54,14 @@ public final class RecentsViewStateController extends if (state.overviewUi) { mRecentsView.updateEmptyMessage(); mRecentsView.resetTaskVisuals(); + mRecentsView.setHintVisibility(1f); + } else { + mRecentsView.setHintVisibility(0f); + ProactiveHintsContainer + proactiveHintsContainer = mRecentsView.getProactiveHintsContainer(); + if (proactiveHintsContainer != null) { + proactiveHintsContainer.removeAllViews(); + } } setAlphas(PropertySetter.NO_ANIM_PROPERTY_SETTER, state.getVisibleElements(mLauncher)); } @@ -64,6 +73,14 @@ public final class RecentsViewStateController extends if (!toState.overviewUi) { builder.addOnFinishRunnable(mRecentsView::resetTaskVisuals); + mRecentsView.setHintVisibility(0f); + builder.addOnFinishRunnable(() -> { + ProactiveHintsContainer + proactiveHintsContainer = mRecentsView.getProactiveHintsContainer(); + if (proactiveHintsContainer != null) { + proactiveHintsContainer.removeAllViews(); + } + }); } if (toState.overviewUi) { @@ -75,6 +92,7 @@ public final class RecentsViewStateController extends updateAnim.setDuration(config.duration); builder.play(updateAnim); mRecentsView.updateEmptyMessage(); + builder.addOnFinishRunnable(() -> mRecentsView.setHintVisibility(1f)); } setAlphas(config.getPropertySetter(builder), toState.getVisibleElements(mLauncher)); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/ProactiveHintsContainer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/ProactiveHintsContainer.java new file mode 100644 index 0000000000..74a48517b2 --- /dev/null +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/hints/ProactiveHintsContainer.java @@ -0,0 +1,55 @@ +package com.android.quickstep.hints; + +import android.content.Context; +import android.util.AttributeSet; +import android.util.FloatProperty; +import android.view.View; +import android.widget.FrameLayout; + +public class ProactiveHintsContainer extends FrameLayout { + + public static final FloatProperty HINT_VISIBILITY = + new FloatProperty("hint_visibility") { + @Override + public void setValue(ProactiveHintsContainer proactiveHintsContainer, float v) { + proactiveHintsContainer.setHintVisibility(v); + } + + @Override + public Float get(ProactiveHintsContainer proactiveHintsContainer) { + return proactiveHintsContainer.mHintVisibility; + } + }; + + private float mHintVisibility; + + public ProactiveHintsContainer(Context context) { + super(context); + } + + public ProactiveHintsContainer(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public ProactiveHintsContainer(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + public ProactiveHintsContainer(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + public void setView(View v) { + removeAllViews(); + addView(v); + } + + public void setHintVisibility(float v) { + if (v == 1) { + setVisibility(VISIBLE); + } else { + setVisibility(GONE); + } + mHintVisibility = v; + } +} diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java index d6f2235031..bdac750de7 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java @@ -34,6 +34,8 @@ import android.os.Build; import android.util.AttributeSet; import android.view.View; +import androidx.annotation.Nullable; + import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; @@ -41,8 +43,11 @@ import com.android.launcher3.R; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.appprediction.PredictionUiStateManager; import com.android.launcher3.appprediction.PredictionUiStateManager.Client; +import com.android.launcher3.util.PendingAnimation; +import com.android.launcher3.views.BaseDragLayer; import com.android.launcher3.views.ScrimView; import com.android.quickstep.SysUINavigationMode; +import com.android.quickstep.hints.ProactiveHintsContainer; import com.android.quickstep.util.ClipAnimationHelper; import com.android.quickstep.util.ClipAnimationHelper.TransformParams; import com.android.quickstep.util.LayoutUtils; @@ -54,6 +59,8 @@ import com.android.quickstep.util.LayoutUtils; public class LauncherRecentsView extends RecentsView { private final TransformParams mTransformParams = new TransformParams(); + private final int mChipOverhang; + @Nullable private ProactiveHintsContainer mProactiveHintsContainer; public LauncherRecentsView(Context context) { this(context, null); @@ -66,6 +73,16 @@ public class LauncherRecentsView extends RecentsView { public LauncherRecentsView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); setContentAlpha(0); + mChipOverhang = (int) context.getResources().getDimension(R.dimen.chip_hint_overhang); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + View hintContainer = mActivity.findViewById(R.id.hints); + mProactiveHintsContainer = + hintContainer instanceof ProactiveHintsContainer + ? (ProactiveHintsContainer) hintContainer : null; } @Override @@ -84,6 +101,11 @@ public class LauncherRecentsView extends RecentsView { } } + @Nullable + public ProactiveHintsContainer getProactiveHintsContainer() { + return mProactiveHintsContainer; + } + @Override public void draw(Canvas canvas) { maybeDrawEmptyMessage(canvas); @@ -137,6 +159,48 @@ public class LauncherRecentsView extends RecentsView { @Override protected void getTaskSize(DeviceProfile dp, Rect outRect) { LayoutUtils.calculateLauncherTaskSize(getContext(), dp, outRect); + if (mProactiveHintsContainer != null) { + BaseDragLayer.LayoutParams params = (BaseDragLayer.LayoutParams) mProactiveHintsContainer.getLayoutParams(); + params.bottomMargin = getHeight() - outRect.bottom - mChipOverhang; + params.width = outRect.width(); + } + } + + @Override + public PendingAnimation createTaskLauncherAnimation(TaskView tv, long duration) { + PendingAnimation anim = super.createTaskLauncherAnimation(tv, duration); + + if (mProactiveHintsContainer != null) { + anim.anim.play(ObjectAnimator.ofFloat( + mProactiveHintsContainer, ProactiveHintsContainer.HINT_VISIBILITY, 0)); + } + + return anim; + } + + @Override + public PendingAnimation createTaskDismissAnimation(TaskView taskView, boolean animateTaskView, + boolean shouldRemoveTask, long duration) { + PendingAnimation anim = super.createTaskDismissAnimation(taskView, animateTaskView, + shouldRemoveTask, duration); + + if (mProactiveHintsContainer != null) { + anim.anim.play(ObjectAnimator.ofFloat( + mProactiveHintsContainer, ProactiveHintsContainer.HINT_VISIBILITY, 0)); + anim.addEndListener(onEndListener -> { + if (!onEndListener.isSuccess) { + mProactiveHintsContainer.setHintVisibility(1); + } + }); + } + + return anim; + } + + public void setHintVisibility(float v) { + if (mProactiveHintsContainer != null) { + mProactiveHintsContainer.setHintVisibility(v); + } } @Override diff --git a/res/layout/launcher.xml b/res/layout/launcher.xml index cca899bda8..9cab9c2a5e 100644 --- a/res/layout/launcher.xml +++ b/res/layout/launcher.xml @@ -48,6 +48,11 @@ layout="@layout/overview_panel" android:visibility="gone" /> + + + + \ No newline at end of file diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 469b176fb4..0da56dafb9 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -235,6 +235,7 @@ 26dp 194dp + 15dp 8dp