summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
diff options
context:
space:
mode:
authorTony Wickham <twickham@google.com>2016-05-16 09:54:06 -0700
committerTony Wickham <twickham@google.com>2016-05-17 18:53:57 -0700
commitf549dab31d0fa3e4d0cf8d6025b20e49aafb2d59 (patch)
treea10ccc74b4d0ad6f353a0a6853950335156c748b /src/com/android/launcher3/pageindicators/PageIndicatorDots.java
parent192ae6ca71b0a1401ad44020b631c634a348597e (diff)
downloadandroid_packages_apps_Trebuchet-f549dab31d0fa3e4d0cf8d6025b20e49aafb2d59.tar.gz
android_packages_apps_Trebuchet-f549dab31d0fa3e4d0cf8d6025b20e49aafb2d59.tar.bz2
android_packages_apps_Trebuchet-f549dab31d0fa3e4d0cf8d6025b20e49aafb2d59.zip
Add PageIndicator interface and custom PageIndicatorLine view.
- The current PageIndicator has been renamed to PageIndicatorDots and PageIndicatorMarker has been renamed to PageIndicatorDot. - PageIndicatorDots and PageIndicatorLine implement PageIndicator. - PageIndicatorLine uses scroll progress and number of pages to draw a line of the correct size and position. - All of these page indicator files are now in a pageindicators package. Bug: 27227498 Change-Id: I9230d2e0600ce583989bd31d0b0e252b148d15c2
Diffstat (limited to 'src/com/android/launcher3/pageindicators/PageIndicatorDots.java')
-rw-r--r--src/com/android/launcher3/pageindicators/PageIndicatorDots.java225
1 files changed, 225 insertions, 0 deletions
diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
new file mode 100644
index 000000000..a488f028a
--- /dev/null
+++ b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2011 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.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 PageIndicatorDots extends LinearLayout implements PageIndicator {
+ @SuppressWarnings("unused")
+ private static final String TAG = "PageIndicator";
+ // Want this to look good? Keep it odd
+ private static final boolean MODULATE_ALPHA_ENABLED = false;
+
+ private LayoutInflater mLayoutInflater;
+ private int[] mWindowRange = new int[2];
+ private int mMaxWindowSize;
+
+ private ArrayList<PageIndicatorDot> mMarkers = new ArrayList<>();
+ @ViewDebug.ExportedProperty(category = "launcher")
+ private int mActiveMarkerIndex;
+
+ public PageIndicatorDots(Context context) {
+ this(context, null);
+ }
+
+ public PageIndicatorDots(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public PageIndicatorDots(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ TypedArray a = context.obtainStyledAttributes(attrs,
+ R.styleable.PageIndicatorDots, defStyle, 0);
+ mMaxWindowSize = a.getInteger(R.styleable.PageIndicatorDots_windowSize, 15);
+ mWindowRange[0] = 0;
+ mWindowRange[1] = 0;
+ mLayoutInflater = LayoutInflater.from(context);
+ a.recycle();
+
+ // Set the layout transition properties
+ LayoutTransition transition = getLayoutTransition();
+ transition.setDuration(175);
+ }
+
+ private void enableLayoutTransitions() {
+ LayoutTransition transition = getLayoutTransition();
+ transition.enableTransitionType(LayoutTransition.APPEARING);
+ transition.enableTransitionType(LayoutTransition.DISAPPEARING);
+ transition.enableTransitionType(LayoutTransition.CHANGE_APPEARING);
+ transition.enableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
+ }
+
+ private void disableLayoutTransitions() {
+ LayoutTransition transition = getLayoutTransition();
+ transition.disableTransitionType(LayoutTransition.APPEARING);
+ transition.disableTransitionType(LayoutTransition.DISAPPEARING);
+ transition.disableTransitionType(LayoutTransition.CHANGE_APPEARING);
+ transition.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
+ }
+
+ public void offsetWindowCenterTo(int activeIndex, boolean allowAnimations) {
+ if (activeIndex < 0) {
+ new Throwable().printStackTrace();
+ }
+ int windowSize = Math.min(mMarkers.size(), mMaxWindowSize);
+ int hWindowSize = (int) windowSize / 2;
+ float hfWindowSize = windowSize / 2f;
+ int windowStart = Math.max(0, activeIndex - hWindowSize);
+ int windowEnd = Math.min(mMarkers.size(), windowStart + mMaxWindowSize);
+ windowStart = windowEnd - Math.min(mMarkers.size(), windowSize);
+ int windowMid = windowStart + (windowEnd - windowStart) / 2;
+ boolean windowAtStart = (windowStart == 0);
+ boolean windowAtEnd = (windowEnd == mMarkers.size());
+ boolean windowMoved = (mWindowRange[0] != windowStart) ||
+ (mWindowRange[1] != windowEnd);
+
+ if (!allowAnimations) {
+ disableLayoutTransitions();
+ }
+
+ // Remove all the previous children that are no longer in the window
+ for (int i = getChildCount() - 1; i >= 0; --i) {
+ PageIndicatorDot marker = (PageIndicatorDot) getChildAt(i);
+ int markerIndex = mMarkers.indexOf(marker);
+ if (markerIndex < windowStart || markerIndex >= windowEnd) {
+ removeView(marker);
+ }
+ }
+
+ // Add all the new children that belong in the window
+ for (int i = 0; i < mMarkers.size(); ++i) {
+ PageIndicatorDot marker = (PageIndicatorDot) mMarkers.get(i);
+ if (windowStart <= i && i < windowEnd) {
+ if (indexOfChild(marker) < 0) {
+ addView(marker, i - windowStart);
+ }
+ if (i == activeIndex) {
+ marker.activate(windowMoved);
+ } else {
+ marker.inactivate(windowMoved);
+ }
+ } else {
+ marker.inactivate(true);
+ }
+
+ if (MODULATE_ALPHA_ENABLED) {
+ // Update the marker's alpha
+ float alpha = 1f;
+ if (mMarkers.size() > windowSize) {
+ if ((windowAtStart && i > hWindowSize) ||
+ (windowAtEnd && i < (mMarkers.size() - hWindowSize)) ||
+ (!windowAtStart && !windowAtEnd)) {
+ alpha = 1f - Math.abs((i - windowMid) / hfWindowSize);
+ }
+ }
+ marker.animate().alpha(alpha).setDuration(500).start();
+ }
+ }
+
+ if (!allowAnimations) {
+ enableLayoutTransitions();
+ }
+
+ mWindowRange[0] = windowStart;
+ mWindowRange[1] = windowEnd;
+ }
+
+ @Override
+ public void addMarker(int index, PageMarkerResources marker, boolean allowAnimations) {
+ index = Math.max(0, Math.min(index, mMarkers.size()));
+
+ 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);
+ }
+
+ @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);
+ }
+ }
+
+ @Override
+ public void updateMarker(int index, PageMarkerResources marker) {
+ PageIndicatorDot m = mMarkers.get(index);
+ m.setMarkerDrawables(marker.activeId, marker.inactiveId);
+ }
+
+ @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);
+ }
+ }
+
+ @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);
+ }
+ }
+
+ @Override
+ public void setActiveMarker(int index) {
+ // Center the active marker
+ mActiveMarkerIndex = index;
+ offsetWindowCenterTo(index, false);
+ }
+
+ private void dumpState(String txt) {
+ System.out.println(txt);
+ System.out.println("\tmMarkers: " + mMarkers.size());
+ for (int i = 0; i < mMarkers.size(); ++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) {
+ PageIndicatorDot m = (PageIndicatorDot) getChildAt(i);
+ System.out.println("\t\t(" + i + ") " + m);
+ }
+ System.out.println("\tactive: " + mActiveMarkerIndex);
+ }
+}