Add scrim below TaskMenu

When opening a menu, a scrim with 80% alpha should be shown on top of
Recents view.

Align task menu second row with icon: when the menu shows up in the
bottom row in landscape, the menu should be aligned on the second row.

TODO: there is a RTL bug that I'm waiting because it also affects other
parts, not only this menu.

Bug: 193432925
Test: open Overview and tap the app icon
Change-Id: I6846ee937cb5e739e8be64d17045bc3b32e28e46
This commit is contained in:
Thales Lima 2021-11-19 13:05:26 -03:00
parent 3c2298668a
commit f316a267d8
4 changed files with 102 additions and 23 deletions

View File

@ -87,6 +87,14 @@ public class IconView extends View {
return mDrawable;
}
public int getDrawableWidth() {
return mDrawableWidth;
}
public int getDrawableHeight() {
return mDrawableHeight;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);

View File

@ -2612,10 +2612,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
clampToProgress(FINAL_FRAME, 0, 0.5f));
});
}
boolean isTaskInBottomGridRow = showAsGrid() && !mTopRowIdSet.contains(
taskView.getTaskViewId()) && taskView.getTaskViewId() != mFocusedTaskViewId;
anim.setFloat(taskView, VIEW_ALPHA, 0,
clampToProgress(isTaskInBottomGridRow ? ACCEL : FINAL_FRAME, 0, 0.5f));
clampToProgress(isOnGridBottomRow(taskView) ? ACCEL : FINAL_FRAME, 0, 0.5f));
FloatProperty<TaskView> secondaryViewTranslate =
taskView.getSecondaryDissmissTranslationProperty();
int secondaryTaskDimension = mOrientationHandler.getSecondaryDimension(taskView);
@ -4681,6 +4679,15 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
return position != -1 ? position : bottomRowIdArray.indexOf(taskView.getTaskViewId());
}
/**
* @return true if the task in on the top of the grid
*/
public boolean isOnGridBottomRow(TaskView taskView) {
return showAsGrid()
&& !mTopRowIdSet.contains(taskView.getTaskViewId())
&& taskView.getTaskViewId() != mFocusedTaskViewId;
}
public Consumer<MotionEvent> getEventDispatcher(float navbarRotation) {
float degreesRotated;
if (navbarRotation == 0) {

View File

@ -45,7 +45,10 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
companion object {
const val TAG = "TaskMenuViewWithArrow"
fun showForTask(taskContainer: TaskIdAttributeContainer): Boolean {
fun showForTask(
taskContainer: TaskIdAttributeContainer,
alignSecondRow: Boolean = false
): Boolean {
val activity = BaseDraggingActivity
.fromContext<BaseDraggingActivity>(taskContainer.taskView.context)
val taskMenuViewWithArrow = activity.layoutInflater
@ -55,7 +58,7 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
false
) as TaskMenuViewWithArrow<*>
return taskMenuViewWithArrow.populateAndShowForTask(taskContainer)
return taskMenuViewWithArrow.populateAndShowForTask(taskContainer, alignSecondRow)
}
}
@ -78,6 +81,9 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
CLOSE_FADE_DURATION = CLOSE_CHILD_FADE_DURATION
}
private var alignSecondRow: Boolean = false
private val extraSpaceForSecondRowAlignment: Int
get() = if (alignSecondRow) optionMeasuredHeight else 0
private val menuWidth = context.resources.getDimensionPixelSize(R.dimen.task_menu_width_grid)
private lateinit var taskView: TaskView
@ -91,6 +97,10 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
else
0
private var iconView: IconView? = null
private var scrim: View? = null
private val scrimAlpha = 0.8f
override fun isOfType(type: Int): Boolean = type and TYPE_TASK_MENU != 0
override fun getTargetObjectLocation(outPos: Rect?) {
@ -112,18 +122,35 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
optionLayout = findViewById(KtR.id.menu_option_layout)
}
private fun populateAndShowForTask(taskContainer: TaskIdAttributeContainer): Boolean {
private fun populateAndShowForTask(
taskContainer: TaskIdAttributeContainer,
alignSecondRow: Boolean
): Boolean {
if (isAttachedToWindow) {
return false
}
taskView = taskContainer.taskView
this.taskContainer = taskContainer
this.alignSecondRow = alignSecondRow
if (!populateMenu()) return false
addScrim()
show()
return true
}
private fun addScrim() {
scrim = View(context).apply {
layoutParams = FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT
)
setBackgroundColor(Themes.getAttrColor(context, R.attr.overviewScrimColor))
alpha = 0f
}
popupContainer.addView(scrim)
}
/** @return true if successfully able to populate task view menu, false otherwise
*/
private fun populateMenu(): Boolean {
@ -180,18 +207,50 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
}
override fun onCreateOpenAnimation(anim: AnimatorSet) {
anim.play(
ObjectAnimator.ofFloat(
taskContainer.thumbnailView, TaskThumbnailView.DIM_ALPHA,
TaskView.MAX_PAGE_SCRIM_ALPHA
scrim?.let {
anim.play(
ObjectAnimator.ofFloat(it, View.ALPHA, 0f, scrimAlpha)
.setDuration(OPEN_DURATION.toLong())
)
)
}
}
override fun onCreateCloseAnimation(anim: AnimatorSet) {
anim.play(
ObjectAnimator.ofFloat(taskContainer.thumbnailView, TaskThumbnailView.DIM_ALPHA, 0f)
)
scrim?.let {
anim.play(
ObjectAnimator.ofFloat(it, View.ALPHA, scrimAlpha, 0f)
.setDuration(CLOSE_DURATION.toLong())
)
}
}
override fun closeComplete() {
super.closeComplete()
popupContainer.removeView(scrim)
popupContainer.removeView(iconView)
}
/**
* Copy the iconView from taskView to dragLayer so it can stay on top of the scrim.
* It needs to be called after [getTargetObjectLocation] because [mTempRect] needs to be
* populated.
*/
private fun copyIconToDragLayer(insets: Rect) {
iconView = IconView(context).apply {
layoutParams = FrameLayout.LayoutParams(
taskContainer.iconView.width,
taskContainer.iconView.height
)
x = mTempRect.left.toFloat() - insets.left
y = mTempRect.top.toFloat() - insets.top
drawable = taskContainer.iconView.drawable
setDrawableSize(
taskContainer.iconView.drawableWidth,
taskContainer.iconView.drawableHeight
)
}
popupContainer.addView(iconView)
}
/**
@ -217,7 +276,10 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
val dragLayer: InsettableFrameLayout = popupContainer
val insets = dragLayer.insets
// Put to the right of the icon if there is space, which means left aligned with the menu
copyIconToDragLayer(insets)
// Put this menu to the right of the icon if there is space,
// which means the arrow is left aligned with the menu
val rightAlignedMenuStartX = mTempRect.left - widthWithArrow
val leftAlignedMenuStartX = mTempRect.right + extraHorizontalSpace
mIsLeftAligned = if (mIsRtl) {
@ -229,18 +291,17 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
var menuStartX = if (mIsLeftAligned) leftAlignedMenuStartX else rightAlignedMenuStartX
// Offset y so that the arrow and first row are center-aligned with the original icon.
// Offset y so that the arrow and row are center-aligned with the original icon.
val iconHeight = mTempRect.height()
val optionHeight = optionMeasuredHeight
val yOffset = (optionHeight - iconHeight) / 2
var menuStartY = mTempRect.top - yOffset
val yOffset = (optionMeasuredHeight - iconHeight) / 2
var menuStartY = mTempRect.top - yOffset - extraSpaceForSecondRowAlignment
// Insets are added later, so subtract them now.
menuStartX -= insets.left
menuStartY -= insets.top
setX(menuStartX.toFloat())
setY(menuStartY.toFloat())
x = menuStartX.toFloat()
y = menuStartY.toFloat()
val lp = layoutParams as FrameLayout.LayoutParams
val arrowLp = mArrow.layoutParams as FrameLayout.LayoutParams
@ -251,7 +312,8 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
override fun addArrow() {
popupContainer.addView(mArrow)
mArrow.x = getArrowX()
mArrow.y = y + (optionMeasuredHeight / 2) - (mArrowHeight / 2)
mArrow.y = y + (optionMeasuredHeight / 2) - (mArrowHeight / 2) +
extraSpaceForSecondRowAlignment
updateArrowColor()

View File

@ -840,7 +840,9 @@ public class TaskView extends FrameLayout implements Reusable {
TaskIdAttributeContainer menuContainer =
mTaskIdAttributeContainer[iconView == mIconView ? 0 : 1];
if (mActivity.getDeviceProfile().overviewShowAsGrid) {
return TaskMenuViewWithArrow.Companion.showForTask(menuContainer);
boolean alignSecondRow = getRecentsView().isOnGridBottomRow(menuContainer.getTaskView())
&& mActivity.getDeviceProfile().isLandscape;
return TaskMenuViewWithArrow.Companion.showForTask(menuContainer, alignSecondRow);
} else {
return TaskMenuView.showForTask(menuContainer);
}