Simplifying some page indicator dots attributes so that it can
be easily modularized
> Moving the color configuration to xml
> Moving auto-hide logic to a subclass as it doesn't
need to be in the main library
Bug: 274011949
Test: Verified on device
Change-Id: Icf7bd5d1cbde3daa9441f2af51f98a931bcd6ee2
diff --git a/quickstep/res/layout/taskbar_edu.xml b/quickstep/res/layout/taskbar_edu.xml
index d7daea3..f3856ba 100644
--- a/quickstep/res/layout/taskbar_edu.xml
+++ b/quickstep/res/layout/taskbar_edu.xml
@@ -55,7 +55,7 @@
style="@style/TaskbarEdu.Button.Close"
android:textColor="?android:attr/textColorPrimary"/>
- <com.android.launcher3.pageindicators.PageIndicatorDots
+ <com.android.launcher3.pageindicators.LauncherDotsPageIndicator
android:id="@+id/content_page_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -63,6 +63,7 @@
app:layout_constraintBottom_toBottomOf="@id/edu_start_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
+ app:indicatorDotColor="@color/folder_pagination_color"
android:elevation="1dp" />
<Button
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduPagedView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduPagedView.java
index 6cd6512..d0e6386 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduPagedView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduPagedView.java
@@ -25,12 +25,12 @@
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.PagedView;
import com.android.launcher3.R;
-import com.android.launcher3.pageindicators.PageIndicatorDots;
+import com.android.launcher3.pageindicators.LauncherDotsPageIndicator;
import com.android.launcher3.taskbar.TaskbarEduController.TaskbarEduCallbacks;
import com.android.launcher3.views.ActivityContext;
/** Horizontal carousel of tutorial screens for Taskbar Edu. */
-public class TaskbarEduPagedView extends PagedView<PageIndicatorDots> {
+public class TaskbarEduPagedView extends PagedView<LauncherDotsPageIndicator> {
private TaskbarEduView mTaskbarEduView;
private TaskbarEduCallbacks mControllerCallbacks;
diff --git a/res/drawable/page_indicator.xml b/res/drawable/page_indicator.xml
deleted file mode 100644
index c0ccc49..0000000
--- a/res/drawable/page_indicator.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
- android:shape="rectangle">
- <solid android:color="?attr/folderPaginationColor"/>
- <size android:width="@dimen/page_indicator_size" android:height="@dimen/page_indicator_size"/>
-</shape>
\ No newline at end of file
diff --git a/res/layout/page_indicator_dots.xml b/res/layout/page_indicator_dots.xml
index d5fe51e..41844b7 100644
--- a/res/layout/page_indicator_dots.xml
+++ b/res/layout/page_indicator_dots.xml
@@ -14,9 +14,13 @@
limitations under the License.
-->
-<com.android.launcher3.pageindicators.PageIndicatorDots xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.launcher3.pageindicators.LauncherDotsPageIndicator
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:id="@+id/page_indicator"
android:layout_width="match_parent"
android:layout_height="@dimen/workspace_page_indicator_height"
android:layout_gravity="bottom | center_horizontal"
- android:theme="@style/HomeScreenElementTheme" />
\ No newline at end of file
+ android:theme="@style/HomeScreenElementTheme"
+ launcher:indicatorDotColor="?attr/workspaceTextColor"
+ />
\ No newline at end of file
diff --git a/res/layout/user_folder_icon_normalized.xml b/res/layout/user_folder_icon_normalized.xml
index 5518dc8..35ccc5a 100644
--- a/res/layout/user_folder_icon_normalized.xml
+++ b/res/layout/user_folder_icon_normalized.xml
@@ -53,12 +53,13 @@
android:textColorHighlight="?android:attr/colorControlHighlight"
android:textColorHint="?attr/folderHintColor"/>
- <com.android.launcher3.pageindicators.PageIndicatorDots
+ <com.android.launcher3.pageindicators.LauncherDotsPageIndicator
android:id="@+id/folder_page_indicator"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:elevation="1dp"
+ launcher:indicatorDotColor="@color/folder_pagination_color"
/>
</LinearLayout>
diff --git a/res/values-night-v31/colors.xml b/res/values-night-v31/colors.xml
index f331361..3b85b88 100644
--- a/res/values-night-v31/colors.xml
+++ b/res/values-night-v31/colors.xml
@@ -26,4 +26,6 @@
<color name="home_settings_track_off_color">@android:color/system_neutral1_700</color>
<color name="all_apps_button_color">@android:color/system_neutral2_200</color>
+
+ <color name="folder_pagination_color">@android:color/system_accent2_100</color>
</resources>
\ No newline at end of file
diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml
index 17fe419..ee27d99 100644
--- a/res/values-night/colors.xml
+++ b/res/values-night/colors.xml
@@ -18,4 +18,6 @@
<resources>
<color name="all_apps_button_color">#BFC8CC</color>
+ <color name="folder_pagination_color">#ffbfebe3</color>
+
</resources>
\ No newline at end of file
diff --git a/res/values-v31/colors.xml b/res/values-v31/colors.xml
index 054fe47..0c87ff4 100644
--- a/res/values-v31/colors.xml
+++ b/res/values-v31/colors.xml
@@ -41,8 +41,7 @@
<color name="wallpaper_popup_scrim">@android:color/system_neutral1_900</color>
<color name="folder_dot_color">@android:color/system_accent3_100</color>
- <color name="folder_pagination_color_light">@android:color/system_accent1_600</color>
- <color name="folder_pagination_color_dark">@android:color/system_accent2_100</color>
+ <color name="folder_pagination_color">@android:color/system_accent1_600</color>
<color name="home_settings_header_accent">@android:color/system_accent1_600</color>
<color name="home_settings_header_collapsed">@android:color/system_neutral1_100</color>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 96938ca..5bacebc 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -42,7 +42,6 @@
<attr name="popupNotificationDotColor" format="color" />
<attr name="folderDotColor" format="color" />
- <attr name="folderPaginationColor" format="color" />
<attr name="folderPreviewColor" format="color" />
<attr name="folderBackgroundColor" format="color" />
<attr name="folderIconRadius" format="float" />
@@ -482,4 +481,10 @@
<!-- The icon drawable of a widget category. -->
<attr name="sectionDrawable" format="reference" />
</declare-styleable>
+
+ <!-- Attributes for PagedIndicator -->
+ <declare-styleable name="PagedIndicator">
+ <!-- Color used to draw dots -->
+ <attr name="indicatorDotColor" format="color" />
+ </declare-styleable>
</resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 8788557..1ef918d 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -67,8 +67,7 @@
<color name="folder_preview_dark">#464746</color>
<color name="folder_dot_color">?attr/colorPrimary</color>
- <color name="folder_pagination_color_light">#ff006c5f</color>
- <color name="folder_pagination_color_dark">#ffbfebe3</color>
+ <color name="folder_pagination_color">#ff006c5f</color>
<color name="text_color_primary_dark">#FFFFFFFF</color>
<color name="text_color_secondary_dark">#FFFFFFFF</color>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 65d215f..01689e4 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -50,7 +50,6 @@
<item name="workspaceStatusBarScrim">@drawable/workspace_bg</item>
<item name="widgetsTheme">@style/WidgetContainerTheme</item>
<item name="folderDotColor">@color/folder_dot_color</item>
- <item name="folderPaginationColor">@color/folder_pagination_color_light</item>
<item name="folderPreviewColor">@color/folder_preview_light</item>
<item name="folderBackgroundColor">@color/folder_background_light</item>
<item name="folderIconBorderColor">?android:attr/colorPrimary</item>
@@ -104,7 +103,6 @@
<item name="popupShadeThird">@color/popup_shade_third_dark</item>
<item name="widgetsTheme">@style/WidgetContainerTheme.Dark</item>
<item name="folderDotColor">@color/folder_dot_color</item>
- <item name="folderPaginationColor">@color/folder_pagination_color_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>
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 22b07ef..5c0fd47 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -85,7 +85,6 @@
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.database.sqlite.SQLiteDatabase;
-import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
@@ -1352,10 +1351,6 @@
if (SHOW_DOT_PAGINATION.get()) {
mWorkspace.getPageIndicator().setShouldAutoHide(true);
- mWorkspace.getPageIndicator().setPaintColor(
- Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText)
- ? Color.BLACK
- : Color.WHITE);
}
}
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index 62e7ef3..26ad4b5 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -153,8 +153,8 @@
Interpolator workspaceFadeInterpolator = config.getInterpolator(ANIM_WORKSPACE_FADE,
pageAlphaProvider.interpolator);
float workspacePageIndicatorAlpha = (elements & WORKSPACE_PAGE_INDICATOR) != 0 ? 1 : 0;
- propertySetter.setViewAlpha(mLauncher.getWorkspace().getPageIndicator(),
- workspacePageIndicatorAlpha, workspaceFadeInterpolator);
+ mLauncher.getWorkspace().getPageIndicator().setAlpha(
+ propertySetter, workspacePageIndicatorAlpha, workspaceFadeInterpolator);
Interpolator hotseatFadeInterpolator = config.getInterpolator(ANIM_HOTSEAT_FADE,
workspaceFadeInterpolator);
float hotseatIconsAlpha = (elements & HOTSEAT_ICONS) != 0 ? 1 : 0;
diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java
index d43731b..9fe3c0b 100644
--- a/src/com/android/launcher3/folder/FolderPagedView.java
+++ b/src/com/android/launcher3/folder/FolderPagedView.java
@@ -45,7 +45,7 @@
import com.android.launcher3.keyboard.ViewGroupFocusHelper;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
-import com.android.launcher3.pageindicators.PageIndicatorDots;
+import com.android.launcher3.pageindicators.LauncherDotsPageIndicator;
import com.android.launcher3.touch.ItemClickHandler;
import com.android.launcher3.util.LauncherBindableItemsContainer.ItemOperator;
import com.android.launcher3.util.Thunk;
@@ -60,7 +60,7 @@
import java.util.function.ToIntFunction;
import java.util.stream.Collectors;
-public class FolderPagedView extends PagedView<PageIndicatorDots> implements ClipPathView {
+public class FolderPagedView extends PagedView<LauncherDotsPageIndicator> implements ClipPathView {
private static final String TAG = "FolderPagedView";
diff --git a/src/com/android/launcher3/pageindicators/LauncherDotsPageIndicator.java b/src/com/android/launcher3/pageindicators/LauncherDotsPageIndicator.java
new file mode 100644
index 0000000..8a21d13
--- /dev/null
+++ b/src/com/android/launcher3/pageindicators/LauncherDotsPageIndicator.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2023 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 static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
+import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE;
+
+import android.animation.ObjectAnimator;
+import android.animation.TimeInterpolator;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.ViewConfiguration;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.Alarm;
+import com.android.launcher3.Insettable;
+import com.android.launcher3.anim.PropertySetter;
+import com.android.launcher3.util.MultiValueAlpha;
+
+/**
+ * Extension of {@link PageIndicatorDots} with Launcher specific page-indicator functionality
+ */
+public class LauncherDotsPageIndicator extends PageIndicatorDots
+ implements Insettable, PageIndicator {
+
+ private static final int PAGINATION_FADE_DELAY = ViewConfiguration.getScrollDefaultDelay();
+ private static final int PAGINATION_FADE_IN_DURATION = 83;
+ private static final int PAGINATION_FADE_OUT_DURATION = 167;
+
+ private static final int INDEX_VIEW_ALPHA = 0;
+ private static final int INDEX_AUTO_HIDE = 1;
+ private static final int ALPHA_CHANNEL_COUNT = 2;
+
+ private final Alarm mAutoHideAlarm;
+ private final MultiValueAlpha mMultiValueAlpha;
+
+ private @Nullable ObjectAnimator mAlphaAnimator;
+ private boolean mShouldAutoHide;
+ private float mTargetAutoHideAlpha;
+
+ private boolean mIsSettled = true;
+ private int mTotalScroll;
+
+ public LauncherDotsPageIndicator(Context context) {
+ this(context, null);
+ }
+
+ public LauncherDotsPageIndicator(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public LauncherDotsPageIndicator(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ mMultiValueAlpha = new MultiValueAlpha(this, ALPHA_CHANNEL_COUNT);
+ mMultiValueAlpha.setUpdateVisibility(true);
+
+ mTargetAutoHideAlpha = mMultiValueAlpha.get(INDEX_AUTO_HIDE).getValue();
+
+ mAutoHideAlarm = new Alarm();
+ mAutoHideAlarm.setOnAlarmListener(a -> animatePaginationToAlpha(0));
+ }
+
+ @Override
+ public void setScroll(int currentScroll, int totalScroll) {
+ mTotalScroll = totalScroll;
+ super.setScroll(currentScroll, totalScroll);
+ }
+
+ @Override
+ public void setShouldAutoHide(boolean shouldAutoHide) {
+ mShouldAutoHide = shouldAutoHide;
+ mAutoHideAlarm.cancelAlarm();
+ if (!mIsSettled || !mShouldAutoHide) {
+ animatePaginationToAlpha(1);
+ } else {
+ mAutoHideAlarm.setAlarm(PAGINATION_FADE_DELAY);
+ }
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (mShouldAutoHide && mTotalScroll == 0) {
+ return;
+ }
+ super.onDraw(canvas);
+ }
+
+ @Override
+ public void setActiveMarker(int activePage) {
+ super.setActiveMarker(activePage);
+ }
+
+ @Override
+ public void setMarkersCount(int numMarkers) {
+ super.setMarkersCount(numMarkers);
+ }
+
+ @Override
+ public void pauseAnimations() {
+ if (mAlphaAnimator != null) {
+ mAlphaAnimator.pause();
+ }
+ }
+
+ @Override
+ public void skipAnimationsToEnd() {
+ if (mAlphaAnimator != null) {
+ mAlphaAnimator.end();
+ }
+ }
+
+ @Override
+ protected void onAnimationStateChanged(boolean isSettled) {
+ mIsSettled = isSettled;
+ if (!mShouldAutoHide) {
+ return;
+ }
+ mAutoHideAlarm.cancelAlarm();
+ if (isSettled) {
+ mAutoHideAlarm.setAlarm(PAGINATION_FADE_DELAY);
+ } else {
+ animatePaginationToAlpha(1f);
+ }
+ }
+
+ private void animatePaginationToAlpha(float targetAlpha) {
+ if (mTargetAutoHideAlpha == targetAlpha) {
+ // Ignore the new animation if it is going to the same alpha as the current animation.
+ return;
+ }
+
+ if (mAlphaAnimator != null) {
+ mAlphaAnimator.cancel();
+ }
+ mAlphaAnimator = ObjectAnimator.ofFloat(mMultiValueAlpha.get(INDEX_AUTO_HIDE),
+ MULTI_PROPERTY_VALUE, targetAlpha);
+ // If we are animating to decrease the alpha, then it's a fade out animation
+ // whereas if we are animating to increase the alpha, it's a fade in animation.
+ mAlphaAnimator.setDuration(targetAlpha == 0
+ ? PAGINATION_FADE_OUT_DURATION
+ : PAGINATION_FADE_IN_DURATION);
+ mAlphaAnimator.addListener(forEndCallback(() -> mAlphaAnimator = null));
+ mAlphaAnimator.start();
+ mTargetAutoHideAlpha = targetAlpha;
+ }
+
+
+ @Override
+ public void stopAllAnimations() {
+ super.stopAllAnimations();
+ }
+
+ @Override
+ public void prepareEntryAnimation() {
+ super.prepareEntryAnimation();
+ }
+
+ @Override
+ public void playEntryAnimation() {
+ super.playEntryAnimation();
+ }
+
+ /**
+ * We need to override setInsets to prevent InsettableFrameLayout from applying different
+ * margins on the pagination.
+ */
+ @Override
+ public void setInsets(Rect insets) {
+ }
+
+ @Override
+ public boolean hasOverlappingRendering() {
+ return false;
+ }
+
+ @Override
+ public void setAlpha(PropertySetter setter, float alpha, TimeInterpolator interpolator) {
+ setter.setFloat(mMultiValueAlpha.get(INDEX_VIEW_ALPHA),
+ MULTI_PROPERTY_VALUE, alpha, interpolator);
+ }
+}
diff --git a/src/com/android/launcher3/pageindicators/PageIndicator.java b/src/com/android/launcher3/pageindicators/PageIndicator.java
index 570d6ff..193f50d 100644
--- a/src/com/android/launcher3/pageindicators/PageIndicator.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicator.java
@@ -15,6 +15,11 @@
*/
package com.android.launcher3.pageindicators;
+import android.animation.TimeInterpolator;
+import android.view.View;
+
+import com.android.launcher3.anim.PropertySetter;
+
/**
* Base class for a page indicator.
*/
@@ -48,9 +53,9 @@
}
/**
- * Sets the paint color.
+ * Sets the provided alpha on the pageIndicator
*/
- default void setPaintColor(int color) {
- // No-op by default
+ default void setAlpha(PropertySetter setter, float alpha, TimeInterpolator interpolator) {
+ setter.setViewAlpha((View) this, alpha, interpolator);
}
}
diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
index b2c64b3..95452b9 100644
--- a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
@@ -25,42 +25,30 @@
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
+import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.Paint.Style;
-import android.graphics.Rect;
import android.graphics.RectF;
-import android.os.Handler;
-import android.os.Looper;
import android.util.AttributeSet;
import android.util.FloatProperty;
-import android.util.IntProperty;
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.Nullable;
-
-import com.android.launcher3.Insettable;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.util.Themes;
/**
* {@link PageIndicator} which shows dots per page. The active page is shown with the current
* accent color.
*/
-public class PageIndicatorDots extends View implements Insettable, PageIndicator {
+public class PageIndicatorDots extends View {
private static final float SHIFT_PER_ANIMATION = 0.5f;
private static final float SHIFT_THRESHOLD = 0.1f;
private static final long ANIMATION_DURATION = 150;
- private static final int PAGINATION_FADE_DELAY = ViewConfiguration.getScrollDefaultDelay();
- private static final int PAGINATION_FADE_IN_DURATION = 83;
- private static final int PAGINATION_FADE_OUT_DURATION = 167;
private static final int ENTER_ANIMATION_START_DELAY = 300;
private static final int ENTER_ANIMATION_STAGGERED_DELAY = 150;
@@ -70,9 +58,6 @@
private static final int DOT_ALPHA = 128;
private static final float DOT_ALPHA_FRACTION = 0.5f;
private static final int DOT_GAP_FACTOR = SHOW_DOT_PAGINATION.get() ? 4 : 3;
- private static final int VISIBLE_ALPHA = 255;
- private static final int INVISIBLE_ALPHA = 0;
- private Paint mPaginationPaint;
// This value approximately overshoots to 1.5 times the original size.
private static final float ENTER_ANIMATION_OVERSHOOT_TENSION = 4.9f;
@@ -94,30 +79,14 @@
}
};
- private static final IntProperty<PageIndicatorDots> PAGINATION_ALPHA =
- new IntProperty<PageIndicatorDots>("pagination_alpha") {
- @Override
- public Integer get(PageIndicatorDots obj) {
- return obj.mPaginationPaint.getAlpha();
- }
-
- @Override
- public void setValue(PageIndicatorDots obj, int alpha) {
- obj.mPaginationPaint.setAlpha(alpha);
- obj.invalidate();
- }
- };
-
- private final Handler mDelayedPaginationFadeHandler = new Handler(Looper.getMainLooper());
private final float mDotRadius;
private final float mCircleGap;
private final boolean mIsRtl;
+ private final Paint mPaginationPaint;
+
private int mNumPages;
private int mActivePage;
- private int mTotalScroll;
- private boolean mShouldAutoHide;
- private int mToAlpha;
/**
* The current position of the active dot including the animation progress.
@@ -131,13 +100,9 @@
private float mCurrentPosition;
private float mFinalPosition;
private ObjectAnimator mAnimator;
- private @Nullable ObjectAnimator mAlphaAnimator;
private float[] mEntryAnimationRadiusFactors;
- private final Runnable mHidePaginationRunnable =
- () -> animatePaginationToAlpha(INVISIBLE_ALPHA);
-
public PageIndicatorDots(Context context) {
this(context, null);
}
@@ -151,37 +116,34 @@
mPaginationPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaginationPaint.setStyle(Style.FILL);
- mPaginationPaint.setColor(Themes.getAttrColor(context, R.attr.folderPaginationColor));
+
+ TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.PagedIndicator);
+ mPaginationPaint.setColor(ta.getColor(R.styleable.PagedIndicator_indicatorDotColor, 0));
+ ta.recycle();
+
mDotRadius = (SHOW_DOT_PAGINATION.get()
? getResources().getDimension(R.dimen.page_indicator_dot_size_v2)
: getResources().getDimension(R.dimen.page_indicator_dot_size))
/ 2;
mCircleGap = DOT_GAP_FACTOR * mDotRadius;
setOutlineProvider(new MyOutlineProver());
- mIsRtl = Utilities.isRtl(getResources());
+ mIsRtl = getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
}
- @Override
public void setScroll(int currentScroll, int totalScroll) {
if (SHOW_DOT_PAGINATION.get() && mActivePage != 0 && currentScroll == 0) {
CURRENT_POSITION.set(this, (float) mActivePage);
return;
}
- if (mNumPages <= 1) {
+ if (mNumPages <= 1 || totalScroll == 0) {
return;
}
- if (mShouldAutoHide) {
- animatePaginationToAlpha(VISIBLE_ALPHA);
- }
-
if (mIsRtl) {
currentScroll = totalScroll - currentScroll;
}
- mTotalScroll = totalScroll;
-
int scrollPerPage = totalScroll / (mNumPages - 1);
int pageToLeft = scrollPerPage == 0 ? 0 : currentScroll / scrollPerPage;
int pageToLeftScroll = pageToLeft * scrollPerPage;
@@ -191,87 +153,12 @@
if (currentScroll < pageToLeftScroll + scrollThreshold) {
// scroll is within the left page's threshold
animateToPosition(pageToLeft);
- if (mShouldAutoHide) {
- hideAfterDelay();
- }
} else if (currentScroll > pageToRightScroll - scrollThreshold) {
// scroll is far enough from left page to go to the right page
animateToPosition(pageToLeft + 1);
- if (mShouldAutoHide) {
- hideAfterDelay();
- }
} else {
// scroll is between left and right page
animateToPosition(pageToLeft + SHIFT_PER_ANIMATION);
- if (mShouldAutoHide) {
- mDelayedPaginationFadeHandler.removeCallbacksAndMessages(null);
- }
- }
- }
-
- @Override
- public void setShouldAutoHide(boolean shouldAutoHide) {
- mShouldAutoHide = shouldAutoHide && SHOW_DOT_PAGINATION.get();
- if (shouldAutoHide && mPaginationPaint.getAlpha() > INVISIBLE_ALPHA) {
- hideAfterDelay();
- } else if (!shouldAutoHide) {
- mDelayedPaginationFadeHandler.removeCallbacksAndMessages(null);
- }
- }
-
- @Override
- public void setPaintColor(int color) {
- mPaginationPaint.setColor(color);
- }
-
- private void hideAfterDelay() {
- mDelayedPaginationFadeHandler.removeCallbacksAndMessages(null);
- mDelayedPaginationFadeHandler.postDelayed(mHidePaginationRunnable, PAGINATION_FADE_DELAY);
- }
-
- private void animatePaginationToAlpha(int alpha) {
- if (alpha == mToAlpha) {
- // Ignore the new animation if it is going to the same alpha as the current animation.
- return;
- }
-
- if (mAlphaAnimator != null) {
- mAlphaAnimator.cancel();
- }
- mAlphaAnimator = ObjectAnimator.ofInt(this, PAGINATION_ALPHA,
- alpha);
- // If we are animating to decrease the alpha, then it's a fade out animation
- // whereas if we are animating to increase the alpha, it's a fade in animation.
- mAlphaAnimator.setDuration(alpha < mToAlpha
- ? PAGINATION_FADE_OUT_DURATION
- : PAGINATION_FADE_IN_DURATION);
- mAlphaAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mAlphaAnimator = null;
- }
- });
- mAlphaAnimator.start();
- mToAlpha = alpha;
- }
-
- /**
- * Pauses all currently running animations.
- */
- @Override
- public void pauseAnimations() {
- if (mAlphaAnimator != null) {
- mAlphaAnimator.pause();
- }
- }
-
- /**
- * Force-ends all currently running or paused animations.
- */
- @Override
- public void skipAnimationsToEnd() {
- if (mAlphaAnimator != null) {
- mAlphaAnimator.end();
}
}
@@ -281,15 +168,25 @@
mCurrentPosition = mFinalPosition;
}
if (mAnimator == null && Float.compare(mCurrentPosition, mFinalPosition) != 0) {
+ onAnimationStateChanged(false);
float positionForThisAnim = mCurrentPosition > mFinalPosition ?
mCurrentPosition - SHIFT_PER_ANIMATION : mCurrentPosition + SHIFT_PER_ANIMATION;
mAnimator = ObjectAnimator.ofFloat(this, CURRENT_POSITION, positionForThisAnim);
mAnimator.addListener(new AnimationCycleListener());
mAnimator.setDuration(ANIMATION_DURATION);
mAnimator.start();
+ } else if (mAnimator == null) {
+ // The state is only settled if the indicator lands on a int value
+ onAnimationStateChanged(Float.compare(Math.round(mFinalPosition), mFinalPosition) == 0);
}
}
+ /**
+ * Called when the animation state of the page indicator changes.
+ * @param isSettled true if the page indicator has settled at its final position
+ */
+ protected void onAnimationStateChanged(boolean isSettled) { }
+
public void stopAllAnimations() {
if (mAnimator != null) {
mAnimator.cancel();
@@ -345,14 +242,10 @@
animSet.start();
}
- @Override
public void setActiveMarker(int activePage) {
- if (mActivePage != activePage) {
- mActivePage = activePage;
- }
+ mActivePage = activePage;
}
- @Override
public void setMarkersCount(int numMarkers) {
mNumPages = numMarkers;
requestLayout();
@@ -374,11 +267,6 @@
return;
}
- if (mShouldAutoHide && mTotalScroll == 0) {
- mPaginationPaint.setAlpha(INVISIBLE_ALPHA);
- return;
- }
-
// Draw all page indicators;
float circleGap = mCircleGap;
float startX = (getWidth() - (mNumPages * circleGap) + mDotRadius) / 2;
@@ -480,20 +368,9 @@
@Override
public void onAnimationEnd(Animator animation) {
if (!mCancelled) {
- if (mShouldAutoHide && SHOW_DOT_PAGINATION.get()) {
- hideAfterDelay();
- }
mAnimator = null;
animateToPosition(mFinalPosition);
}
}
}
-
- /**
- * We need to override setInsets to prevent InsettableFrameLayout from applying different
- * margins on the pagination.
- */
- @Override
- public void setInsets(Rect insets) {
- }
}