Merge changes from topic "pid-iv" into main
* changes: Implement Folder Pagination Arrow Hover / Pressed UX Moved PageIndicatorDots to their own ImageViews.
This commit is contained in:
committed by
Android (Google) Code Review
commit
12f5ccddd3
@@ -6,6 +6,6 @@
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:autoMirrored="true">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:fillColor="?attr/pageIndicatorDotColor"
|
||||
android:pathData="M464,480L604,620Q622,638 622,664Q622,690 604,708Q586,726 560,726Q534,726 516,708L333,525Q324,516 319,504Q314,492 314,480Q314,468 319,456Q324,444 333,435L516,252Q534,234 560,234Q586,234 604,252Q622,270 622,296Q622,322 604,340L464,480Z"/>
|
||||
</vector>
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="@dimen/folder_arrow_icon_length"
|
||||
android:height="@dimen/folder_arrow_icon_length"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:autoMirrored="true">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M472,480L332,340Q314,322 314,296Q314,270 332,252Q350,234 376,234Q402,234 420,252L603,435Q612,444 617,456Q622,468 622,480Q622,492 617,504Q612,516 603,525L420,708Q402,726 376,726Q350,726 332,708Q314,690 314,664Q314,638 332,620L472,480Z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (C) 2025 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="?attr/pageIndicatorArrowBgColor"
|
||||
android:pathData="M480,880Q397,880 324,848.5Q251,817 197,763Q143,709 111.5,636Q80,563 80,480Q80,397 111.5,324Q143,251 197,197Q251,143 324,111.5Q397,80 480,80Q563,80 636,111.5Q709,143 763,197Q817,251 848.5,324Q880,397 880,480Q880,563 848.5,636Q817,709 763,763Q709,817 636,848.5Q563,880 480,880Z"/>
|
||||
</vector>
|
||||
|
||||
@@ -53,6 +53,16 @@
|
||||
android:textColorHighlight="?android:attr/colorControlHighlight"
|
||||
android:textColorHint="?attr/folderHintTextColor"/>
|
||||
|
||||
<com.android.launcher3.pageindicators.PaginationArrow
|
||||
android:id="@+id/left_indicator_arrow"
|
||||
android:layout_width="@dimen/folder_arrow_touchbox_length"
|
||||
android:layout_height="@dimen/folder_arrow_touchbox_length"
|
||||
android:foreground="@drawable/ic_chevron_left_rounded_700"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:foregroundGravity="center"
|
||||
android:contentDescription="@string/paginate_left"
|
||||
android:elevation="1dp"/>
|
||||
|
||||
<com.android.launcher3.pageindicators.PageIndicatorDots
|
||||
android:id="@+id/folder_page_indicator"
|
||||
android:layout_gravity="center_vertical"
|
||||
@@ -61,6 +71,16 @@
|
||||
android:elevation="1dp"
|
||||
/>
|
||||
|
||||
<com.android.launcher3.pageindicators.PaginationArrow
|
||||
android:id="@+id/right_indicator_arrow"
|
||||
android:layout_width="@dimen/folder_arrow_touchbox_length"
|
||||
android:layout_height="@dimen/folder_arrow_touchbox_length"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:foreground="@drawable/ic_chevron_left_rounded_700"
|
||||
android:rotation="180"
|
||||
android:contentDescription="@string/paginate_right"
|
||||
android:foregroundGravity="center"
|
||||
android:elevation="1dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
</com.android.launcher3.folder.Folder>
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
|
||||
|
||||
<attr name="pageIndicatorDotColor" format="color" />
|
||||
<attr name="pageIndicatorArrowBgColor" format="color" />
|
||||
<attr name="folderPreviewColor" format="color" />
|
||||
<attr name="folderBackgroundColor" format="color" />
|
||||
<attr name="folderIconRadius" format="float" />
|
||||
|
||||
@@ -75,6 +75,9 @@
|
||||
<color name="pagination_indicator_dot_color_light">#0B57D0</color>
|
||||
<color name="pagination_indicator_dot_color_dark">#A8C7FA</color>
|
||||
|
||||
<color name="page_indicator_arrow_bg_light">#000000</color>
|
||||
<color name="page_indicator_arrow_bg_dark">#FFFFFF</color>
|
||||
|
||||
<color name="text_color_primary_dark">#FFFFFFFF</color>
|
||||
<color name="text_color_secondary_dark">#FFFFFFFF</color>
|
||||
<color name="text_color_tertiary_dark">#CCFFFFFF</color>
|
||||
|
||||
@@ -545,6 +545,7 @@
|
||||
<!-- Folder spaces -->
|
||||
<dimen name="folder_top_padding_default">24dp</dimen>
|
||||
<dimen name="folder_footer_horiz_padding">20dp</dimen>
|
||||
<dimen name="folder_arrow_touchbox_length">32dp</dimen>
|
||||
|
||||
<!-- Default Ime height. Used only for logging purposes.
|
||||
Assume this is default keyboard height in EN locale in case the keyboard height is not known when queried.-->
|
||||
|
||||
@@ -272,6 +272,8 @@
|
||||
|
||||
<!-- Default folder title -->
|
||||
<string name="folder_hint_text">Edit Name</string>
|
||||
<string name="paginate_left">Paginate left</string>
|
||||
<string name="paginate_right">Paginate right</string>
|
||||
|
||||
<!-- Accessibility -->
|
||||
<!-- The format string for when an app is temporarily disabled. -->
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
<item name="workspaceKeyShadowColor">#89000000</item>
|
||||
<item name="widgetsTheme">@style/WidgetContainerTheme</item>
|
||||
<item name="pageIndicatorDotColor">@color/page_indicator_dot_color_light</item>
|
||||
<item name="pageIndicatorArrowBgColor">@color/page_indicator_arrow_bg_light</item>
|
||||
<item name="focusOutlineColor">@color/materialColorSecondaryFixed</item>
|
||||
<item name="focusInnerOutlineColor">@color/materialColorOnSecondaryFixedVariant</item>
|
||||
<item name="folderPreviewColor">@color/folder_preview_light</item>
|
||||
@@ -130,6 +131,7 @@
|
||||
<item name="notificationDotColor">@color/notification_dot_color_dark</item>
|
||||
<item name="widgetsTheme">@style/WidgetContainerTheme.Dark</item>
|
||||
<item name="pageIndicatorDotColor">@color/page_indicator_dot_color_dark</item>
|
||||
<item name="pageIndicatorArrowBgColor">@color/page_indicator_arrow_bg_dark</item>
|
||||
<item name="folderPreviewColor">@color/folder_preview_dark</item>
|
||||
<item name="folderBackgroundColor">@color/folder_background_dark</item>
|
||||
<item name="folderIconBorderColor">?android:attr/colorPrimary</item>
|
||||
|
||||
@@ -28,6 +28,8 @@ import static com.android.launcher3.folder.FolderGridOrganizer.createFolderGridO
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_LABEL_UPDATED;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROP_COMPLETED;
|
||||
import static com.android.launcher3.model.data.FolderInfo.willAcceptItemType;
|
||||
import static com.android.launcher3.pageindicators.PaginationArrow.DISABLED_ARROW_OPACITY;
|
||||
import static com.android.launcher3.pageindicators.PaginationArrow.FULLY_OPAQUE;
|
||||
import static com.android.launcher3.testing.shared.TestProtocol.FOLDER_OPENED_MESSAGE;
|
||||
import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
|
||||
|
||||
@@ -100,6 +102,7 @@ import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.model.data.WorkspaceItemFactory;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
import com.android.launcher3.pageindicators.PageIndicatorDots;
|
||||
import com.android.launcher3.pageindicators.PaginationArrow;
|
||||
import com.android.launcher3.util.Executors;
|
||||
import com.android.launcher3.util.LauncherBindableItemsContainer;
|
||||
import com.android.launcher3.util.Thunk;
|
||||
@@ -208,6 +211,8 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
||||
FolderPagedView mContent;
|
||||
private FolderNameEditText mFolderName;
|
||||
private PageIndicatorDots mPageIndicator;
|
||||
private PaginationArrow mLeftArrow;
|
||||
private PaginationArrow mRightArrow;
|
||||
|
||||
protected View mFooter;
|
||||
private int mFooterHeight;
|
||||
@@ -316,6 +321,15 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
||||
mFolderName.forceDisableSuggestions(true);
|
||||
mKeyboardInsetAnimationCallback = new KeyboardInsetAnimationCallback(this);
|
||||
setWindowInsetsAnimationCallback(mKeyboardInsetAnimationCallback);
|
||||
|
||||
if (enableLauncherVisualRefresh()) {
|
||||
mLeftArrow = findViewById(R.id.left_indicator_arrow);
|
||||
mRightArrow = findViewById(R.id.right_indicator_arrow);
|
||||
mRightArrow.setOnClickListener(v -> mContent.snapToPage(
|
||||
mContent.getCurrentPage() + 1));
|
||||
mLeftArrow.setOnClickListener(v -> mContent.snapToPage(
|
||||
mContent.getCurrentPage() - 1));
|
||||
}
|
||||
}
|
||||
|
||||
/** If arrows are visible, replace the container padding with indicator padding */
|
||||
@@ -324,13 +338,28 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo
|
||||
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);
|
||||
mLeftArrow.setVisibility(View.VISIBLE);
|
||||
mRightArrow.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mFooter.setPadding(sidePadding, 0, sidePadding, 0);
|
||||
mPageIndicator.setPadding(0, 0, 0, 0);
|
||||
((MarginLayoutParams) mFolderName.getLayoutParams()).setMarginStart(0);
|
||||
mLeftArrow.setVisibility(View.GONE);
|
||||
mRightArrow.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the page is switched. Sets arrow UX to a disabled appearance if the page is at
|
||||
* one end or the other.
|
||||
*/
|
||||
public void updateArrowAlphas() {
|
||||
if (enableLauncherVisualRefresh()) {
|
||||
mLeftArrow.setAlpha(
|
||||
0 == mContent.getCurrentPage() ? DISABLED_ARROW_OPACITY : FULLY_OPAQUE);
|
||||
mRightArrow.setAlpha(mContent.getPageCount() == mContent.getCurrentPage() + 1
|
||||
? DISABLED_ARROW_OPACITY : FULLY_OPAQUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,6 @@ import com.android.launcher3.keyboard.ViewGroupFocusHelper;
|
||||
import com.android.launcher3.model.data.AppPairInfo;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
import com.android.launcher3.pageindicators.Direction;
|
||||
import com.android.launcher3.pageindicators.PageIndicatorDots;
|
||||
import com.android.launcher3.util.LauncherBindableItemsContainer.ItemOperator;
|
||||
import com.android.launcher3.util.Thunk;
|
||||
@@ -131,8 +130,6 @@ public class FolderPagedView extends PagedView<PageIndicatorDots> implements Cli
|
||||
public void setFolder(Folder folder) {
|
||||
mFolder = folder;
|
||||
mPageIndicator = folder.findViewById(R.id.folder_page_indicator);
|
||||
mPageIndicator.setArrowClickListener(direction -> snapToPage(
|
||||
(Direction.END == direction) ? mCurrentPage + 1 : mCurrentPage - 1));
|
||||
initParentViews(folder);
|
||||
}
|
||||
|
||||
@@ -489,6 +486,7 @@ public class FolderPagedView extends PagedView<PageIndicatorDots> implements Cli
|
||||
super.notifyPageSwitchListener(prevPage);
|
||||
if (mFolder != null) {
|
||||
mFolder.updateTextViewFocus();
|
||||
mFolder.updateArrowAlphas();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package com.android.launcher3.pageindicators;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Base class for a page indicator.
|
||||
*/
|
||||
@@ -28,14 +26,6 @@ public interface PageIndicator {
|
||||
|
||||
void setMarkersCount(int numMarkers);
|
||||
|
||||
/**
|
||||
* This is only going to be used by the FolderPagedView's PageIndicator. A refactor is planned
|
||||
* to separate the two purposes of this class, but in the meantime, this indicator will serve to
|
||||
* let the folder snap to the page of its click, and also tell the PageIndicator not to draw
|
||||
* arrows if the click listener is null (at least until after this is refactored).
|
||||
*/
|
||||
void setArrowClickListener(Consumer<Direction> listener);
|
||||
|
||||
/**
|
||||
* Sets a flag indicating whether to pause scroll.
|
||||
* <p>Should be set to {@code true} while the screen is binding or new data is being applied,
|
||||
|
||||
@@ -27,39 +27,30 @@ import android.animation.ValueAnimator;
|
||||
import android.animation.ValueAnimator.AnimatorUpdateListener;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.VectorDrawable;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.FloatProperty;
|
||||
import android.util.IntProperty;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.ViewOutlineProvider;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.view.animation.OvershootInterpolator;
|
||||
|
||||
import androidx.annotation.DrawableRes;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.launcher3.Insettable;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.util.Themes;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* {@link PageIndicator} which shows dots per page. The active page is shown with the current
|
||||
* accent color.
|
||||
@@ -75,15 +66,12 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator
|
||||
private static final int PAGINATION_FADE_IN_DURATION = 83;
|
||||
private static final int PAGINATION_FADE_OUT_DURATION = 167;
|
||||
|
||||
private static final int DISABLED_ARROW_OPACITY = 97; // 38%
|
||||
|
||||
private static final int ENTER_ANIMATION_START_DELAY = 300;
|
||||
private static final int ENTER_ANIMATION_STAGGERED_DELAY = 150;
|
||||
private static final int ENTER_ANIMATION_DURATION = 400;
|
||||
|
||||
private static final int HEIGHT_MULTIPLIER = 4;
|
||||
private static final int WIDTH_MULTIPLIER = 3;
|
||||
private static final float ARROW_TOUCH_BOX_FACTOR = 2f;
|
||||
|
||||
private static final int PAGE_INDICATOR_ALPHA = 255;
|
||||
private static final int DOT_ALPHA = 128;
|
||||
@@ -92,7 +80,6 @@ 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 @Nullable Consumer<Direction> mOnArrowClickListener;
|
||||
|
||||
// This value approximately overshoots to 1.5 times the original size.
|
||||
private static final float ENTER_ANIMATION_OVERSHOOT_TENSION = 4.9f;
|
||||
@@ -135,14 +122,6 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator
|
||||
private final float mGapWidth;
|
||||
private final float mCircleGap;
|
||||
private final boolean mIsRtl;
|
||||
private final VectorDrawable mArrowRight;
|
||||
private final VectorDrawable mArrowLeft;
|
||||
private final Rect mArrowRightBounds = new Rect();
|
||||
private final Rect mArrowLeftBounds = new Rect();
|
||||
private final int mArrowTouchBoxExtraWidth;
|
||||
private final int mArrowTouchBoxHeight;
|
||||
private final int mArrowGapWidth;
|
||||
private final int mArrowLength;
|
||||
|
||||
private int mNumPages;
|
||||
private int mActivePage;
|
||||
@@ -194,23 +173,6 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator
|
||||
: DOT_GAP_FACTOR * mDotRadius;
|
||||
setOutlineProvider(new MyOutlineProver());
|
||||
mIsRtl = Utilities.isRtl(getResources());
|
||||
mArrowRight = setupArrow(R.drawable.ic_chevron_right_rounded_700);
|
||||
mArrowLeft = setupArrow(R.drawable.ic_chevron_left_rounded_700);
|
||||
/* the width of the arrows themselves plus extra folder / touch padding. x2 for 2 arrows. */
|
||||
mArrowTouchBoxExtraWidth = 2 * ((int) ((5.5f) * mGapWidth)
|
||||
+ getResources().getDimensionPixelSize(R.dimen.folder_footer_horiz_padding));
|
||||
mArrowTouchBoxHeight =
|
||||
getResources().getDimensionPixelSize(R.dimen.folder_footer_height_default);
|
||||
mArrowLength = getResources().getDimensionPixelSize(R.dimen.folder_arrow_icon_length);
|
||||
mArrowGapWidth = getResources().getDimensionPixelSize(R.dimen.folder_arrow_gap_width);
|
||||
}
|
||||
|
||||
private VectorDrawable setupArrow(@DrawableRes int resId) {
|
||||
VectorDrawable icon = (VectorDrawable) ContextCompat.getDrawable(getContext(), resId);
|
||||
ColorFilter arrowColorFilter = new PorterDuffColorFilter(mPaginationPaint.getColor(),
|
||||
PorterDuff.Mode.SRC_ATOP);
|
||||
icon.setColorFilter(arrowColorFilter);
|
||||
return icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -448,11 +410,6 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setArrowClickListener(@Nullable Consumer<Direction> listener) {
|
||||
mOnArrowClickListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPauseScroll(boolean pause, boolean isTwoPanels) {
|
||||
mIsTwoPanels = isTwoPanels;
|
||||
@@ -467,20 +424,13 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
// TODO(b/394355070): Verify Folder Entry Animation works correctly with visual updates
|
||||
// Add extra spacing of mDotRadius on all sides so than entry animation could be run
|
||||
// and so the hitboxes of arrows can be clicked easier.
|
||||
int width = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY ?
|
||||
MeasureSpec.getSize(widthMeasureSpec)
|
||||
: (int) ((mNumPages * WIDTH_MULTIPLIER + 2) * mDotRadius);
|
||||
int height = MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY
|
||||
? MeasureSpec.getSize(heightMeasureSpec)
|
||||
: (int) (HEIGHT_MULTIPLIER * mDotRadius);
|
||||
if (enableLauncherVisualRefresh() && mOnArrowClickListener != null) {
|
||||
// Extra height and width and gaps for accessibility arrows.
|
||||
width += mArrowTouchBoxExtraWidth;
|
||||
height = mArrowTouchBoxHeight;
|
||||
}
|
||||
setMeasuredDimension(width, height);
|
||||
}
|
||||
|
||||
@@ -573,17 +523,6 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator
|
||||
float bounceProgress = (posDif > 1) ? posDif - 1 : 0;
|
||||
float bounceAdjustment = Math.abs(currentPosition - boundedPosition) * diameter;
|
||||
|
||||
if (mOnArrowClickListener != null) {
|
||||
// Here we draw the Left Arrow
|
||||
mArrowLeft.setAlpha(boundedPosition == 0 ? DISABLED_ARROW_OPACITY : alpha);
|
||||
mArrowLeftBounds.left = (int) (sTempRect.left - mArrowGapWidth - mArrowLength);
|
||||
mArrowLeftBounds.top = (int) (y - (float) mArrowLength / 2);
|
||||
mArrowLeftBounds.right = mArrowLeftBounds.left + mArrowLength;
|
||||
mArrowLeftBounds.bottom = mArrowLeftBounds.top + mArrowLength;
|
||||
mArrowLeft.setBounds(mArrowLeftBounds);
|
||||
mArrowLeft.draw(canvas);
|
||||
}
|
||||
|
||||
// Here we draw the dots, one at a time from the left-most dot to the right-most dot
|
||||
// 1.0 => 000000 000000111111 000000
|
||||
// 1.3 => 000000 0000001111 11000000
|
||||
@@ -640,17 +579,6 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator
|
||||
sTempRect.left = sTempRect.right + mGapWidth;
|
||||
}
|
||||
|
||||
if (mOnArrowClickListener != null) {
|
||||
// Here we draw the Right Arrow
|
||||
mArrowRight.setAlpha(boundedPosition == (mNumPages - 1)
|
||||
? DISABLED_ARROW_OPACITY : alpha);
|
||||
mArrowRightBounds.left = (int) (sTempRect.left - mGapWidth + mArrowGapWidth);
|
||||
mArrowRightBounds.top = (int) (y - (float) mArrowLength / 2);
|
||||
mArrowRightBounds.right = mArrowRightBounds.left + mArrowLength;
|
||||
mArrowRightBounds.bottom = mArrowRightBounds.top + mArrowLength;
|
||||
mArrowRight.setBounds(mArrowRightBounds);
|
||||
mArrowRight.draw(canvas);
|
||||
}
|
||||
} else {
|
||||
// Here we draw the dots
|
||||
mPaginationPaint.setAlpha((int) (alpha * DOT_ALPHA_FRACTION));
|
||||
@@ -668,27 +596,6 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator
|
||||
mPaginationPaint.setAlpha(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
if (mOnArrowClickListener == null) {
|
||||
// No - Op. Don't care about touch events
|
||||
} else if ((mIsRtl && withinExpandedBounds(mArrowRightBounds, ev))
|
||||
|| (!mIsRtl && withinExpandedBounds(mArrowLeftBounds, ev))) {
|
||||
mOnArrowClickListener.accept(Direction.START);
|
||||
} else if ((mIsRtl && withinExpandedBounds(mArrowLeftBounds, ev))
|
||||
|| (!mIsRtl && withinExpandedBounds(mArrowRightBounds, ev))) {
|
||||
mOnArrowClickListener.accept(Direction.END);
|
||||
}
|
||||
return super.onTouchEvent(ev);
|
||||
}
|
||||
|
||||
// For larger Touch box
|
||||
private boolean withinExpandedBounds(Rect rect, MotionEvent ev) {
|
||||
RectF scaledRect = new RectF(rect);
|
||||
scale(scaledRect, ARROW_TOUCH_BOX_FACTOR);
|
||||
return scaledRect.contains(ev.getX(), ev.getY());
|
||||
}
|
||||
|
||||
private static void scale(RectF rect, float factor) {
|
||||
float horizontalAdjustment = rect.width() * (factor - 1) / 2;
|
||||
float verticalAdjustment = rect.height() * (factor - 1) / 2;
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2025 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.launcher3.pageindicators
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.MotionEvent
|
||||
import android.widget.ImageView
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.android.launcher3.R
|
||||
|
||||
/**
|
||||
* Handles logic for the pagination arrow. The foreground and background images and the pressed /
|
||||
* hovered state UX.
|
||||
*/
|
||||
@SuppressLint("AppCompatCustomView")
|
||||
class PaginationArrow(context: Context, attrs: AttributeSet) : ImageView(context, attrs) {
|
||||
private val bgCircle = ContextCompat.getDrawable(context, R.drawable.ic_circle)
|
||||
|
||||
init {
|
||||
foreground = ContextCompat.getDrawable(context, R.drawable.ic_chevron_left_rounded_700)
|
||||
}
|
||||
|
||||
override fun onTouchEvent(event: MotionEvent?): Boolean {
|
||||
when (event?.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
background = bgCircle
|
||||
background.alpha = BACKGROUND_PRESSED_OPACITY
|
||||
}
|
||||
MotionEvent.ACTION_UP -> background = null
|
||||
}
|
||||
return super.onTouchEvent(event)
|
||||
}
|
||||
|
||||
override fun onHoverEvent(event: MotionEvent?): Boolean {
|
||||
when (event?.action) {
|
||||
MotionEvent.ACTION_HOVER_ENTER -> {
|
||||
background = bgCircle
|
||||
background.alpha = BACKGROUND_HOVERED_OPACITY
|
||||
}
|
||||
MotionEvent.ACTION_HOVER_EXIT -> background = null
|
||||
}
|
||||
return super.onHoverEvent(event)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val FULLY_OPAQUE = 1f
|
||||
const val DISABLED_ARROW_OPACITY = .38f
|
||||
|
||||
// alpha ints are 0 - 255; the former being transparent and the latter being fully opaque
|
||||
private const val BACKGROUND_HOVERED_OPACITY = 28 // 11%
|
||||
private const val BACKGROUND_PRESSED_OPACITY = 38 // 15%
|
||||
}
|
||||
}
|
||||
@@ -26,12 +26,9 @@ import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.pageindicators.Direction;
|
||||
import com.android.launcher3.pageindicators.PageIndicator;
|
||||
import com.android.launcher3.views.ActivityContext;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Supports two indicator colors, dedicated for personal and work tabs.
|
||||
*/
|
||||
@@ -80,11 +77,6 @@ public class PersonalWorkSlidingTabStrip extends LinearLayout implements PageInd
|
||||
public void setMarkersCount(int numMarkers) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setArrowClickListener(Consumer<Direction> listener) {
|
||||
// No-Op. All Apps doesn't need accessibility arrows for single click navigation.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOverlappingRendering() {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user