Merge "Add PageIndicator interface and custom PageIndicatorLine view." into ub-launcher3-calgary

This commit is contained in:
Tony Wickham
2016-05-18 02:09:02 +00:00
committed by Android (Google) Code Review
17 changed files with 345 additions and 85 deletions
+3 -5
View File
@@ -57,12 +57,10 @@
<!-- Keep these behind the workspace so that they are not visible when
we go into AllApps -->
<include
<com.android.launcher3.pageindicators.PageIndicatorLine
android:id="@+id/page_indicator"
layout="@layout/page_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
android:layout_width="match_parent"
android:layout_height="1dp" />
<include
android:id="@+id/app_info_drop_target_bar"
+4 -5
View File
@@ -64,11 +64,10 @@
<!-- Keep these behind the workspace so that they are not visible when
we go into AllApps -->
<include android:id="@+id/page_indicator"
layout="@layout/page_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<com.android.launcher3.pageindicators.PageIndicatorLine
android:id="@+id/page_indicator"
android:layout_width="match_parent"
android:layout_height="1dp" />
<include layout="@layout/widgets_view"
android:id="@+id/widgets_view"
+2 -2
View File
@@ -13,9 +13,9 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<com.android.launcher3.PageIndicator
<com.android.launcher3.pageindicators.PageIndicatorDots
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:animateLayoutChanges="true"
launcher:windowSize="@integer/config_maxNumberOfPageIndicatorsToShow">
</com.android.launcher3.PageIndicator>
</com.android.launcher3.pageindicators.PageIndicatorDots>
+2 -2
View File
@@ -13,7 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<com.android.launcher3.PageIndicatorMarker
<com.android.launcher3.pageindicators.PageIndicatorDot
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:layout_width="12dp"
@@ -36,4 +36,4 @@
android:scaleX="0.5"
android:scaleY="0.5"
/>
</com.android.launcher3.PageIndicatorMarker>
</com.android.launcher3.pageindicators.PageIndicatorDot>
+1 -1
View File
@@ -32,7 +32,7 @@
</declare-styleable>
<!-- Page Indicator specific attributes. -->
<declare-styleable name="PageIndicator">
<declare-styleable name="PageIndicatorDots">
<attr name="windowSize" format="integer" />
</declare-styleable>
@@ -537,7 +537,6 @@ public class DeviceProfile {
lp = (FrameLayout.LayoutParams) pageIndicator.getLayoutParams();
lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
lp.width = LayoutParams.WRAP_CONTENT;
lp.height = LayoutParams.WRAP_CONTENT;
lp.bottomMargin = hotseatBarHeightPx;
pageIndicator.setLayoutParams(lp);
}
+7 -4
View File
@@ -112,6 +112,8 @@ import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.logging.LoggerUtils;
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.pageindicators.PageIndicator;
import com.android.launcher3.pageindicators.PageIndicatorLine;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.logging.FileLog;
@@ -224,7 +226,7 @@ public class Launcher extends Activity
@Thunk Workspace mWorkspace;
private View mLauncherView;
private View mPageIndicators;
private PageIndicatorLine mPageIndicator;
@Thunk DragLayer mDragLayer;
private DragController mDragController;
@@ -501,6 +503,7 @@ public class Launcher extends Activity
if (mExtractedColors != null && Utilities.isNycOrAbove()) {
mExtractedColors.load(this);
mHotseat.updateColor(mExtractedColors, !mPaused);
mPageIndicator.updateColor(mExtractedColors);
}
}
@@ -1327,7 +1330,7 @@ public class Launcher extends Activity
mFocusHandler = (FocusIndicatorView) findViewById(R.id.focus_indicator);
mDragLayer = (DragLayer) findViewById(R.id.drag_layer);
mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);
mPageIndicators = mDragLayer.findViewById(R.id.page_indicator);
mPageIndicator = (PageIndicatorLine) mDragLayer.findViewById(R.id.page_indicator);
mLauncherView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
@@ -4530,7 +4533,7 @@ public class Launcher extends Activity
void showWorkspaceSearchAndHotseat() {
if (mWorkspace != null) mWorkspace.setAlpha(1f);
if (mHotseat != null) mHotseat.setAlpha(1f);
if (mPageIndicators != null) mPageIndicators.setAlpha(1f);
if (mPageIndicator != null) mPageIndicator.setAlpha(1f);
if (mSearchDropTargetBar != null) mSearchDropTargetBar.animateToState(
SearchDropTargetBar.State.SEARCH_BAR, 0);
}
@@ -4538,7 +4541,7 @@ public class Launcher extends Activity
void hideWorkspaceSearchAndHotseat() {
if (mWorkspace != null) mWorkspace.setAlpha(0f);
if (mHotseat != null) mHotseat.setAlpha(0f);
if (mPageIndicators != null) mPageIndicators.setAlpha(0f);
if (mPageIndicator != null) mPageIndicator.setAlpha(0f);
if (mSearchDropTargetBar != null) mSearchDropTargetBar.animateToState(
SearchDropTargetBar.State.INVISIBLE, 0);
}
+16 -9
View File
@@ -49,8 +49,11 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.Interpolator;
import com.android.launcher3.pageindicators.PageIndicator;
import com.android.launcher3.util.LauncherEdgeEffect;
import com.android.launcher3.util.Thunk;
import java.util.ArrayList;
/**
@@ -254,8 +257,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
mPageIndicator = (PageIndicator) grandParent.findViewById(mPageIndicatorViewId);
mPageIndicator.removeAllMarkers(true);
ArrayList<PageIndicator.PageMarkerResources> markers =
new ArrayList<PageIndicator.PageMarkerResources>();
ArrayList<PageIndicator.PageMarkerResources> markers = new ArrayList<>();
for (int i = 0; i < getChildCount(); ++i) {
markers.add(getPageIndicatorMarker(i));
}
@@ -264,9 +266,9 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
OnClickListener listener = getPageIndicatorClickListener();
if (listener != null) {
mPageIndicator.setOnClickListener(listener);
mPageIndicator.getView().setOnClickListener(listener);
}
mPageIndicator.setContentDescription(getPageIndicatorDescription());
mPageIndicator.getView().setContentDescription(getPageIndicatorDescription());
}
}
@@ -355,7 +357,8 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
return mPageIndicator;
}
protected PageIndicator.PageMarkerResources getPageIndicatorMarker(int pageIndex) {
return new PageIndicator.PageMarkerResources();
return new PageIndicator.PageMarkerResources(R.drawable.ic_pageindicator_current,
R.drawable.ic_pageindicator_default);
}
/**
@@ -430,7 +433,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
Math.min(newPage, mTempVisiblePagesRange[1]));
}
// Ensure that it is clamped by the actual set of children in all cases
validatedPage = Utilities.boundInRange(validatedPage, 0, getPageCount() - 1);
validatedPage = Utilities.boundToRange(validatedPage, 0, getPageCount() - 1);
return validatedPage;
}
@@ -475,7 +478,7 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
private void updatePageIndicator() {
// Update the page indicator (when we aren't reordering)
if (mPageIndicator != null) {
mPageIndicator.setContentDescription(getPageIndicatorDescription());
mPageIndicator.getView().setContentDescription(getPageIndicatorDescription());
if (!isReordering(false)) {
mPageIndicator.setActiveMarker(getNextPage());
}
@@ -931,12 +934,16 @@ public abstract class PagedView extends ViewGroup implements ViewGroup.OnHierarc
}
@Thunk void updateMaxScrollX() {
mMaxScrollX = computeMaxScrollX();
}
protected int computeMaxScrollX() {
int childCount = getChildCount();
if (childCount > 0) {
final int index = mIsRtl ? 0 : childCount - 1;
mMaxScrollX = getScrollForPage(index);
return getScrollForPage(index);
} else {
mMaxScrollX = 0;
return 0;
}
}
@@ -194,7 +194,7 @@ public class PinchAnimationManager {
animateShowHideView(INDEX_HOTSEAT, mLauncher.getHotseat(), show);
if (mWorkspace.getPageIndicator() != null) {
// There aren't page indicators in landscape mode on phones, hence the null check.
animateShowHideView(INDEX_PAGE_INDICATOR, mWorkspace.getPageIndicator(), show);
animateShowHideView(INDEX_PAGE_INDICATOR, mWorkspace.getPageIndicator().getView(), show);
}
}
+8 -1
View File
@@ -798,7 +798,14 @@ public final class Utilities {
* If value is less than lowerBound, return lowerBound; else if value is greater than upperBound,
* return upperBound; else return value unchanged.
*/
public static int boundInRange(int value, int lowerBound, int upperBound) {
public static int boundToRange(int value, int lowerBound, int upperBound) {
return Math.max(lowerBound, Math.min(value, upperBound));
}
/**
* @see #boundToRange(int, int, int).
*/
public static float boundToRange(float value, float lowerBound, float upperBound) {
return Math.max(lowerBound, Math.min(value, upperBound));
}
+27 -5
View File
@@ -73,6 +73,7 @@ import com.android.launcher3.dragndrop.SpringLoadedDragController;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.pageindicators.PageIndicator;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
import com.android.launcher3.util.LongArrayMap;
@@ -1272,6 +1273,22 @@ public class Workspace extends PagedView
super.scrollTo(x, y);
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
// Update the page indicator progress.
boolean isTransitioning = mIsSwitchingState
|| (getLayoutTransition() != null && getLayoutTransition().isRunning());
if (mPageIndicator != null && !isTransitioning) {
showPageIndicatorAtCurrentScroll();
}
}
private void showPageIndicatorAtCurrentScroll() {
mPageIndicator.setProgress((float) getScrollX() / computeMaxScrollX());
}
@Override
protected void overScroll(float amount) {
boolean shouldOverScroll = (amount <= 0 && (!hasCustomContent() || mIsRtl)) ||
@@ -1325,7 +1342,7 @@ public class Workspace extends PagedView
// different effects based on device performance. On at least one relatively high-end
// device I've tried, translating the launcher causes things to get quite laggy.
setTranslationAndAlpha(mLauncher.getSearchDropTargetBar(), transX, alpha);
setTranslationAndAlpha(getPageIndicator(), transX, alpha);
setTranslationAndAlpha(getPageIndicator().getView(), transX, alpha);
setTranslationAndAlpha(getChildAt(getCurrentPage()), transX, alpha);
setTranslationAndAlpha(mLauncher.getHotseat(), transX, alpha);
@@ -1538,7 +1555,7 @@ public class Workspace extends PagedView
}
if (getPageIndicator() != null) {
getPageIndicator().setTranslationX(translationX);
getPageIndicator().getView().setTranslationX(translationX);
}
if (mCustomContentCallbacks != null) {
@@ -1587,8 +1604,10 @@ public class Workspace extends PagedView
// attach to window
OnClickListener listener = getPageIndicatorClickListener();
if (listener != null) {
getPageIndicator().setOnClickListener(listener);
getPageIndicator().getView().setOnClickListener(listener);
}
showPageIndicatorAtCurrentScroll();
}
// Update wallpaper dimensions if they were changed since last onResume
@@ -1739,8 +1758,8 @@ public class Workspace extends PagedView
super.getVisiblePages(range);
if (mForceDrawAdjacentPages) {
// In overview mode, make sure that the two side pages are visible.
range[0] = Utilities.boundInRange(getCurrentPage() - 1, numCustomPages(), range[1]);
range[1] = Utilities.boundInRange(getCurrentPage() + 1, range[0], getPageCount() - 1);
range[0] = Utilities.boundToRange(getCurrentPage() - 1, numCustomPages(), range[1]);
range[1] = Utilities.boundToRange(getCurrentPage() + 1, range[0], getPageCount() - 1);
}
}
@@ -2006,6 +2025,9 @@ public class Workspace extends PagedView
updateChildrenLayersEnabled(false);
showCustomContentIfNecessary();
mForceDrawAdjacentPages = false;
if (mState == State.NORMAL || mState == State.SPRING_LOADED) {
showPageIndicatorAtCurrentScroll();
}
}
void updateCustomContentVisibility() {
@@ -288,7 +288,7 @@ public class WorkspaceStateTransitionAnimation {
float finalBackgroundAlpha = (states.stateIsSpringLoaded || states.stateIsOverview) ?
1.0f : 0f;
float finalHotseatAlpha = (states.stateIsNormal || states.stateIsSpringLoaded) ? 1f : 0f;
float finalPageIndicatorAlpha = states.stateIsNormal ? 1f : 0f;
float finalPageIndicatorAlpha = finalHotseatAlpha;
float finalOverviewPanelAlpha = states.stateIsOverview ? 1f : 0f;
float finalWorkspaceTranslationY = 0;
@@ -357,7 +357,7 @@ public class WorkspaceStateTransitionAnimation {
final ViewGroup overviewPanel = mLauncher.getOverviewPanel();
final View hotseat = mLauncher.getHotseat();
final View pageIndicator = mWorkspace.getPageIndicator();
final View pageIndicator = mWorkspace.getPageIndicator().getView();
if (animated) {
LauncherViewPropertyAnimator scale = new LauncherViewPropertyAnimator(mWorkspace);
scale.scaleX(mNewScale)
@@ -39,8 +39,8 @@ import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.PageIndicator;
import com.android.launcher3.PageIndicator.PageMarkerResources;
import com.android.launcher3.pageindicators.PageIndicatorDots;
import com.android.launcher3.pageindicators.PageIndicator.PageMarkerResources;
import com.android.launcher3.PagedView;
import com.android.launcher3.R;
import com.android.launcher3.ShortcutAndWidgetContainer;
@@ -103,7 +103,7 @@ public class FolderPagedView extends PagedView {
private FocusIndicatorView mFocusIndicatorView;
private PagedFolderKeyEventListener mKeyListener;
private PageIndicator mPageIndicator;
private PageIndicatorDots mPageIndicator;
public FolderPagedView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -128,7 +128,7 @@ public class FolderPagedView extends PagedView {
mFolder = folder;
mFocusIndicatorView = (FocusIndicatorView) folder.findViewById(R.id.focus_indicator);
mKeyListener = new PagedFolderKeyEventListener(folder);
mPageIndicator = (PageIndicator) folder.findViewById(R.id.folder_page_indicator);
mPageIndicator = (PageIndicatorDots) folder.findViewById(R.id.folder_page_indicator);
}
/**
@@ -0,0 +1,31 @@
package com.android.launcher3.pageindicators;
import android.view.View;
import java.util.ArrayList;
public interface PageIndicator {
View getView();
void setProgress(float progress);
void removeAllMarkers(boolean allowAnimations);
void addMarkers(ArrayList<PageMarkerResources> markers, boolean allowAnimations);
void setActiveMarker(int activePage);
void addMarker(int pageIndex, PageMarkerResources pageIndicatorMarker, boolean allowAnimations);
void removeMarker(int pageIndex, boolean allowAnimations);
void updateMarker(int pageIndex, PageMarkerResources pageIndicatorMarker);
/**
* Contains two resource ids for each page indicator marker (e.g. dots):
* one for when the page is active and one for when the page is inactive.
*/
class PageMarkerResources {
int activeId;
int inactiveId;
public PageMarkerResources(int aId, int iaId) {
activeId = aId;
inactiveId = iaId;
}
}
}
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.launcher3;
package com.android.launcher3.pageindicators;
import android.content.Context;
import android.content.res.Resources;
@@ -22,7 +22,9 @@ import android.util.AttributeSet;
import android.widget.FrameLayout;
import android.widget.ImageView;
public class PageIndicatorMarker extends FrameLayout {
import com.android.launcher3.R;
public class PageIndicatorDot extends FrameLayout {
@SuppressWarnings("unused")
private static final String TAG = "PageIndicator";
@@ -32,15 +34,15 @@ public class PageIndicatorMarker extends FrameLayout {
private ImageView mInactiveMarker;
private boolean mIsActive = false;
public PageIndicatorMarker(Context context) {
public PageIndicatorDot(Context context) {
this(context, null);
}
public PageIndicatorMarker(Context context, AttributeSet attrs) {
public PageIndicatorDot(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PageIndicatorMarker(Context context, AttributeSet attrs, int defStyle) {
public PageIndicatorDot(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@@ -14,19 +14,22 @@
* limitations under the License.
*/
package com.android.launcher3;
package com.android.launcher3.pageindicators;
import android.animation.LayoutTransition;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewDebug;
import android.widget.LinearLayout;
import com.android.launcher3.R;
import java.util.ArrayList;
public class PageIndicator extends LinearLayout {
public class PageIndicatorDots extends LinearLayout implements PageIndicator {
@SuppressWarnings("unused")
private static final String TAG = "PageIndicator";
// Want this to look good? Keep it odd
@@ -36,38 +39,23 @@ public class PageIndicator extends LinearLayout {
private int[] mWindowRange = new int[2];
private int mMaxWindowSize;
private ArrayList<PageIndicatorMarker> mMarkers =
new ArrayList<PageIndicatorMarker>();
private ArrayList<PageIndicatorDot> mMarkers = new ArrayList<>();
@ViewDebug.ExportedProperty(category = "launcher")
private int mActiveMarkerIndex;
public static class PageMarkerResources {
int activeId;
int inactiveId;
public PageMarkerResources() {
activeId = R.drawable.ic_pageindicator_current;
inactiveId = R.drawable.ic_pageindicator_default;
}
public PageMarkerResources(int aId, int iaId) {
activeId = aId;
inactiveId = iaId;
}
}
public PageIndicator(Context context) {
public PageIndicatorDots(Context context) {
this(context, null);
}
public PageIndicator(Context context, AttributeSet attrs) {
public PageIndicatorDots(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PageIndicator(Context context, AttributeSet attrs, int defStyle) {
public PageIndicatorDots(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.PageIndicator, defStyle, 0);
mMaxWindowSize = a.getInteger(R.styleable.PageIndicator_windowSize, 15);
R.styleable.PageIndicatorDots, defStyle, 0);
mMaxWindowSize = a.getInteger(R.styleable.PageIndicatorDots_windowSize, 15);
mWindowRange[0] = 0;
mWindowRange[1] = 0;
mLayoutInflater = LayoutInflater.from(context);
@@ -94,7 +82,7 @@ public class PageIndicator extends LinearLayout {
transition.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
}
void offsetWindowCenterTo(int activeIndex, boolean allowAnimations) {
public void offsetWindowCenterTo(int activeIndex, boolean allowAnimations) {
if (activeIndex < 0) {
new Throwable().printStackTrace();
}
@@ -116,7 +104,7 @@ public class PageIndicator extends LinearLayout {
// Remove all the previous children that are no longer in the window
for (int i = getChildCount() - 1; i >= 0; --i) {
PageIndicatorMarker marker = (PageIndicatorMarker) getChildAt(i);
PageIndicatorDot marker = (PageIndicatorDot) getChildAt(i);
int markerIndex = mMarkers.indexOf(marker);
if (markerIndex < windowStart || markerIndex >= windowEnd) {
removeView(marker);
@@ -125,7 +113,7 @@ public class PageIndicator extends LinearLayout {
// Add all the new children that belong in the window
for (int i = 0; i < mMarkers.size(); ++i) {
PageIndicatorMarker marker = (PageIndicatorMarker) mMarkers.get(i);
PageIndicatorDot marker = (PageIndicatorDot) mMarkers.get(i);
if (windowStart <= i && i < windowEnd) {
if (indexOfChild(marker) < 0) {
addView(marker, i - windowStart);
@@ -161,58 +149,75 @@ public class PageIndicator extends LinearLayout {
mWindowRange[1] = windowEnd;
}
void addMarker(int index, PageMarkerResources marker, boolean allowAnimations) {
@Override
public void addMarker(int index, PageMarkerResources marker, boolean allowAnimations) {
index = Math.max(0, Math.min(index, mMarkers.size()));
PageIndicatorMarker m =
(PageIndicatorMarker) mLayoutInflater.inflate(R.layout.page_indicator_marker,
PageIndicatorDot m =
(PageIndicatorDot) mLayoutInflater.inflate(R.layout.page_indicator_marker,
this, false);
m.setMarkerDrawables(marker.activeId, marker.inactiveId);
mMarkers.add(index, m);
offsetWindowCenterTo(mActiveMarkerIndex, allowAnimations);
}
void addMarkers(ArrayList<PageMarkerResources> markers, boolean allowAnimations) {
@Override
public void addMarkers(ArrayList<PageMarkerResources> markers, boolean allowAnimations) {
for (int i = 0; i < markers.size(); ++i) {
addMarker(Integer.MAX_VALUE, markers.get(i), allowAnimations);
}
}
void updateMarker(int index, PageMarkerResources marker) {
PageIndicatorMarker m = mMarkers.get(index);
@Override
public void updateMarker(int index, PageMarkerResources marker) {
PageIndicatorDot m = mMarkers.get(index);
m.setMarkerDrawables(marker.activeId, marker.inactiveId);
}
void removeMarker(int index, boolean allowAnimations) {
@Override
public void removeMarker(int index, boolean allowAnimations) {
if (mMarkers.size() > 0) {
index = Math.max(0, Math.min(mMarkers.size() - 1, index));
mMarkers.remove(index);
offsetWindowCenterTo(mActiveMarkerIndex, allowAnimations);
}
}
void removeAllMarkers(boolean allowAnimations) {
@Override
public View getView() {
return this;
}
@Override
public void setProgress(float progress) {
}
@Override
public void removeAllMarkers(boolean allowAnimations) {
while (mMarkers.size() > 0) {
removeMarker(Integer.MAX_VALUE, allowAnimations);
}
}
void setActiveMarker(int index) {
@Override
public void setActiveMarker(int index) {
// Center the active marker
mActiveMarkerIndex = index;
offsetWindowCenterTo(index, false);
}
void dumpState(String txt) {
private void dumpState(String txt) {
System.out.println(txt);
System.out.println("\tmMarkers: " + mMarkers.size());
for (int i = 0; i < mMarkers.size(); ++i) {
PageIndicatorMarker m = mMarkers.get(i);
PageIndicatorDot m = mMarkers.get(i);
System.out.println("\t\t(" + i + ") " + m);
}
System.out.println("\twindow: [" + mWindowRange[0] + ", " + mWindowRange[1] + "]");
System.out.println("\tchildren: " + getChildCount());
for (int i = 0; i < getChildCount(); ++i) {
PageIndicatorMarker m = (PageIndicatorMarker) getChildAt(i);
PageIndicatorDot m = (PageIndicatorDot) getChildAt(i);
System.out.println("\t\t(" + i + ") " + m);
}
System.out.println("\tactive: " + mActiveMarkerIndex);
@@ -0,0 +1,187 @@
package com.android.launcher3.pageindicators;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.graphics.ColorUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Property;
import android.view.View;
import android.view.ViewConfiguration;
import com.android.launcher3.Utilities;
import com.android.launcher3.dynamicui.ExtractedColors;
import java.util.ArrayList;
/**
* A PageIndicator that briefly shows a fraction of a line when moving between pages.
*
* The fraction is 1 / number of pages and the position is based on the progress of the page scroll.
*/
public class PageIndicatorLine extends View implements PageIndicator {
private static final String TAG = "PageIndicatorLine";
private static final int LINE_FADE_DURATION = ViewConfiguration.getScrollBarFadeDuration();
private static final int LINE_FADE_DELAY = ViewConfiguration.getScrollDefaultDelay();
public static final int WHITE_ALPHA = (int) (0.70f * 255);
public static final int BLACK_ALPHA = (int) (0.65f * 255);
private final Handler mHandler = new Handler(Looper.getMainLooper());
private ValueAnimator mLineAlphaAnimator;
private int mAlpha = 0;
private float mProgress = 0f;
private int mNumPages = 1;
private Paint mLinePaint;
private Property<Paint, Integer> mPaintAlphaProperty
= new Property<Paint, Integer>(Integer.class, "paint_alpha") {
@Override
public Integer get(Paint paint) {
return paint.getAlpha();
}
@Override
public void set(Paint paint, Integer alpha) {
paint.setAlpha(alpha);
invalidate();
}
};
private Runnable mHideLineRunnable = new Runnable() {
@Override
public void run() {
animateLineToAlpha(0);
}
};
public PageIndicatorLine(Context context) {
this(context, null);
}
public PageIndicatorLine(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PageIndicatorLine(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mLinePaint = new Paint();
mLinePaint.setAlpha(0);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mNumPages == 0) {
return;
}
int availableWidth = canvas.getWidth();
int lineWidth = availableWidth / mNumPages;
int lineLeft = (int) (mProgress * (availableWidth - lineWidth));
int lineRight = lineLeft + lineWidth;
canvas.drawRect(lineLeft, 0, lineRight, canvas.getHeight(), mLinePaint);
}
@Override
public View getView() {
return this;
}
@Override
public void setProgress(float progress) {
if (getAlpha() == 0) {
return;
}
progress = Utilities.boundToRange(progress, 0f, 1f);
animateLineToAlpha(mAlpha);
mProgress = progress;
invalidate();
// Hide after a brief period.
mHandler.removeCallbacksAndMessages(null);
mHandler.postDelayed(mHideLineRunnable, LINE_FADE_DELAY);
}
@Override
public void removeAllMarkers(boolean allowAnimations) {
mNumPages = 0;
}
@Override
public void addMarkers(ArrayList<PageMarkerResources> markers, boolean allowAnimations) {
mNumPages += markers.size();
}
@Override
public void setActiveMarker(int activePage) {
}
@Override
public void addMarker(int pageIndex, PageMarkerResources pageIndicatorMarker,
boolean allowAnimations) {
mNumPages++;
}
@Override
public void removeMarker(int pageIndex, boolean allowAnimations) {
mNumPages--;
}
@Override
public void updateMarker(int pageIndex, PageMarkerResources pageIndicatorMarker) {
}
/**
* The line's color will be:
* - mostly opaque white if the hotseat is white (ignoring alpha)
* - mostly opaque black if the hotseat is black (ignoring alpha)
*/
public void updateColor(ExtractedColors extractedColors) {
int originalLineAlpha = mLinePaint.getAlpha();
int color = extractedColors.getColor(ExtractedColors.HOTSEAT_INDEX, Color.TRANSPARENT);
if (color != Color.TRANSPARENT) {
color = ColorUtils.setAlphaComponent(color, 255);
if (color == Color.BLACK) {
mAlpha = BLACK_ALPHA;
} else if (color == Color.WHITE) {
mAlpha = WHITE_ALPHA;
} else {
Log.e(TAG, "Setting workspace page indicators to an unsupported color: #"
+ Integer.toHexString(color));
}
mLinePaint.setColor(color);
mLinePaint.setAlpha(originalLineAlpha);
}
}
private void animateLineToAlpha(int alpha) {
if (mLineAlphaAnimator != null) {
// An animation is already running, so ignore the new animation request unless we are
// trying to hide the line, in which case we always allow the animation.
if (alpha != 0) {
return;
}
mLineAlphaAnimator.cancel();
}
mLineAlphaAnimator = ObjectAnimator.ofInt(mLinePaint, mPaintAlphaProperty, alpha);
mLineAlphaAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mLineAlphaAnimator = null;
}
});
mLineAlphaAnimator.setDuration(LINE_FADE_DURATION);
mLineAlphaAnimator.start();
}
}