From 8860d1eca953fafd98b65915152025e44fb2f3a5 Mon Sep 17 00:00:00 2001 From: Stefan Andonian Date: Fri, 21 Mar 2025 15:06:45 -0700 Subject: [PATCH] PageIndicatorDot Placement && Arrow Touchboxes. In the previous image tests, the page indicator placement within folders was inconsistent depending on the number of pages in a folder. This change fixes that by removing the margin_End for the page indicator in folders, as well as fixing the onMeasure call in PageIndicatorDots to be the same as the legacy calculation, just with additional space for the arrows. Previously, the touchboxes were very small, and difficult to use. To enlarge the touchbox, enlarged padding is used. This means when the indicator & arrows are visible, we need to remove the margin from the layout container and move it to padding for the indicator. Bug: 394355070 Test: Tested folders with 2, 3, and 18 pages in both left to right and right to left mode. Flag: com.android.launcher3.enable_launcher_visual_refresh Change-Id: I3a5d9d6d77dec963865adede1c4bfe38890d608f --- src/com/android/launcher3/folder/Folder.java | 28 +++++++++++++------ .../launcher3/folder/FolderPagedView.java | 4 +++ .../pageindicators/PageIndicatorDots.java | 28 ++++++++++++------- 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java index d1c6a4f39a..8f2e4b70a1 100644 --- a/src/com/android/launcher3/folder/Folder.java +++ b/src/com/android/launcher3/folder/Folder.java @@ -298,13 +298,6 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo mContent.setFolder(this); mPageIndicator = findViewById(R.id.folder_page_indicator); - if (enableLauncherVisualRefresh()) { - MarginLayoutParams params = ((MarginLayoutParams) mPageIndicator.getLayoutParams()); - int horizontalMargin = getContext().getResources() - .getDimensionPixelSize(R.dimen.folder_footer_horiz_padding); - params.setMarginStart(horizontalMargin); - params.setMarginEnd(horizontalMargin); - } mFooter = findViewById(R.id.folder_footer); mFooterHeight = dp.folderFooterHeightPx; mFolderName = findViewById(R.id.folder_name); @@ -317,11 +310,26 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_FLAG_CAP_WORDS); mFolderName.forceDisableSuggestions(true); - mKeyboardInsetAnimationCallback = new KeyboardInsetAnimationCallback(this); setWindowInsetsAnimationCallback(mKeyboardInsetAnimationCallback); } + /** If arrows are visible, replace the container padding with indicator padding */ + public void onIndicatorVisibilityChanged() { + int sidePadding = getResources().getDimensionPixelSize(R.dimen.folder_footer_horiz_padding); + if (mPageIndicator.getVisibility() == View.VISIBLE) { + // Replace the container padding with indicator padding for arrows + mFooter.setPadding(0, 0, 0, 0); + mPageIndicator.setPadding(sidePadding, 0, sidePadding, 0); + ((MarginLayoutParams) mFolderName.getLayoutParams()) + .setMarginStart(sidePadding); + } else { + mFooter.setPadding(sidePadding, 0, sidePadding, 0); + mPageIndicator.setPadding(0, 0, 0, 0); + ((MarginLayoutParams) mFolderName.getLayoutParams()).setMarginStart(0); + } + } + public boolean onLongClick(View v) { // Return if global dragging is not enabled if (!getIsLauncherDraggingEnabled()) return true; @@ -1278,7 +1286,9 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo super.onSizeChanged(w, h, oldw, oldh); int minTitleWidth = getResources().getDimensionPixelSize(R.dimen.folder_title_min_width); if (enableLauncherVisualRefresh() && mFolderName.getMeasuredWidth() < minTitleWidth) { - mFolderName.setVisibility(View.GONE); + ((MarginLayoutParams) mFolderName.getLayoutParams()).setMarginStart(0); + // The post is necessary for margins to be recalculated. RTL UI is shifted otherwise. + mFolderName.post(() -> mFolderName.setVisibility(View.GONE)); } } diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java index 0963421f8a..4a60390477 100644 --- a/src/com/android/launcher3/folder/FolderPagedView.java +++ b/src/com/android/launcher3/folder/FolderPagedView.java @@ -18,6 +18,7 @@ package com.android.launcher3.folder; import static com.android.launcher3.AbstractFloatingView.TYPE_ALL; import static com.android.launcher3.AbstractFloatingView.TYPE_FOLDER; +import static com.android.launcher3.Flags.enableLauncherVisualRefresh; import static com.android.launcher3.folder.FolderGridOrganizer.createFolderGridOrganizer; import android.annotation.SuppressLint; @@ -390,6 +391,9 @@ public class FolderPagedView extends PagedView implements Cli // Update footer mPageIndicator.setVisibility(getPageCount() > 1 ? View.VISIBLE : View.GONE); + if (enableLauncherVisualRefresh()) { + mFolder.onIndicatorVisibilityChanged(); + } // Set the gravity as LEFT or RIGHT instead of START, as START depends on the actual text. int horizontalGravity = getPageCount() > 1 ? (mIsRtl ? Gravity.RIGHT : Gravity.LEFT) : Gravity.CENTER_HORIZONTAL; diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java index 8f80515e36..8cd835490c 100644 --- a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java +++ b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java @@ -75,10 +75,8 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator private static final int ENTER_ANIMATION_STAGGERED_DELAY = 150; private static final int ENTER_ANIMATION_DURATION = 400; - private static final int LARGE_HEIGHT_MULTIPLIER = 12; - private static final int SMALL_HEIGHT_MULTIPLIER = 4; - private static final int LARGE_WIDTH_MULTIPLIER = 5; - private static final int SMALL_WIDTH_MULTIPLIER = 3; + private static final int HEIGHT_MULTIPLIER = 4; + private static final int WIDTH_MULTIPLIER = 3; private static final float ARROW_TOUCH_BOX_FACTOR = 5f; private static final int PAGE_INDICATOR_ALPHA = 255; @@ -88,7 +86,7 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator private static final int VISIBLE_ALPHA = 255; private static final int INVISIBLE_ALPHA = 0; private Paint mPaginationPaint; - private Consumer mOnArrowClickListener; + private @Nullable Consumer mOnArrowClickListener; // This value approximately overshoots to 1.5 times the original size. private static final float ENTER_ANIMATION_OVERSHOOT_TENSION = 4.9f; @@ -135,6 +133,8 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator private final VectorDrawable mArrowLeft; private final Rect mArrowRightBounds = new Rect(); private final Rect mArrowLeftBounds = new Rect(); + private final int mArrowWidth; + private final int mArrowHeight; private int mNumPages; private int mActivePage; @@ -188,6 +188,11 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator mIsRtl = Utilities.isRtl(getResources()); mArrowRight = (VectorDrawable) getResources().getDrawable(R.drawable.ic_chevron_end); mArrowLeft = (VectorDrawable) getResources().getDrawable(R.drawable.ic_chevron_start); + /* the width of the arrows themselves plus extra folder / touch padding. x2 for 2 arrows. */ + mArrowWidth = 2 * ((int) ((5.5f) * mGapWidth) + + getResources().getDimensionPixelSize(R.dimen.folder_footer_horiz_padding)); + mArrowHeight = + getResources().getDimensionPixelSize(R.dimen.folder_footer_height_default); } @Override @@ -426,7 +431,7 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator } @Override - public void setArrowClickListener(Consumer listener) { + public void setArrowClickListener(@Nullable Consumer listener) { mOnArrowClickListener = listener; } @@ -449,12 +454,15 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator // and so the hitboxes of arrows can be clicked easier. int width = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY ? MeasureSpec.getSize(widthMeasureSpec) - : (int) ((mNumPages * ((enableLauncherVisualRefresh()) - ? LARGE_WIDTH_MULTIPLIER : SMALL_WIDTH_MULTIPLIER) + 2) * mDotRadius); + : (int) ((mNumPages * WIDTH_MULTIPLIER + 2) * mDotRadius); int height = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY ? MeasureSpec.getSize(heightMeasureSpec) - : (int) (((enableLauncherVisualRefresh()) - ? LARGE_HEIGHT_MULTIPLIER : SMALL_HEIGHT_MULTIPLIER) * mDotRadius); + : (int) (HEIGHT_MULTIPLIER * mDotRadius); + if (enableLauncherVisualRefresh() && mOnArrowClickListener != null) { + // Extra height and width and gaps for accessibility arrows. + width += mArrowWidth; + height = mArrowHeight; + } setMeasuredDimension(width, height); }