summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSunny Goyal <sunnygoyal@google.com>2016-10-08 17:43:48 -0700
committerSunny Goyal <sunnygoyal@google.com>2016-10-10 14:17:16 -0700
commit5d9fb0e92f2ef2b25f3aa93c1f89838ccc68aa88 (patch)
tree46764e909a89e51c294ca23b0eed69a481fa9333
parent631ffbda64b92b843f18af6756b52b1ac4c22461 (diff)
downloadandroid_packages_apps_Trebuchet-5d9fb0e92f2ef2b25f3aa93c1f89838ccc68aa88.tar.gz
android_packages_apps_Trebuchet-5d9fb0e92f2ef2b25f3aa93c1f89838ccc68aa88.tar.bz2
android_packages_apps_Trebuchet-5d9fb0e92f2ef2b25f3aa93c1f89838ccc68aa88.zip
Simplifying fast scroller logic
> Using a separate view for drawing the popup. This allows us to use elevation property instead of drawing the shadow as bitmap. > During the thumb animation, invalidating the full track width, instead of invalidating the track and thumb separately. > The thumb path is calculated at 0,0 and drawn using canvas.translate(). This avoids recalculating the path on every scroll. Change-Id: I48741e5b4432df0d939016db284d7aaf52cc2aa6
-rw-r--r--res/layout/all_apps.xml16
-rw-r--r--res/layout/widgets_view.xml16
-rw-r--r--res/values/dimens.xml1
-rw-r--r--src/com/android/launcher3/BaseRecyclerView.java25
-rw-r--r--src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java270
-rw-r--r--src/com/android/launcher3/BaseRecyclerViewFastScrollPopup.java198
-rw-r--r--src/com/android/launcher3/allapps/AllAppsContainerView.java2
-rw-r--r--src/com/android/launcher3/allapps/AllAppsRecyclerView.java13
-rw-r--r--src/com/android/launcher3/graphics/HolographicOutlineHelper.java22
-rw-r--r--src/com/android/launcher3/widget/WidgetsRecyclerView.java2
10 files changed, 200 insertions, 365 deletions
diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml
index 926883927..d48bd500e 100644
--- a/res/layout/all_apps.xml
+++ b/res/layout/all_apps.xml
@@ -55,6 +55,22 @@
android:focusable="true"
android:theme="@style/CustomOverscroll.Light" />
+ <!-- Fast scroller popup -->
+ <TextView
+ android:background="@drawable/container_fastscroll_popup_bg"
+ android:layout_width="@dimen/container_fastscroll_popup_size"
+ android:layout_height="@dimen/container_fastscroll_popup_size"
+ android:textSize="@dimen/container_fastscroll_popup_text_size"
+ android:layout_below="@+id/search_container"
+ android:id="@+id/fast_scroller_popup"
+ android:layout_alignParentEnd="true"
+ android:gravity="center"
+ android:alpha="0"
+ android:elevation="3dp"
+ android:saveEnabled="false"
+ android:layout_marginEnd="@dimen/container_fastscroll_popup_margin"
+ android:textColor="@android:color/white" />
+
<FrameLayout
android:id="@+id/search_container"
android:layout_width="match_parent"
diff --git a/res/layout/widgets_view.xml b/res/layout/widgets_view.xml
index c4431be25..2cf951938 100644
--- a/res/layout/widgets_view.xml
+++ b/res/layout/widgets_view.xml
@@ -49,6 +49,22 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
+ <!-- Fast scroller popup -->
+ <TextView
+ android:background="@drawable/container_fastscroll_popup_bg"
+ android:layout_width="@dimen/container_fastscroll_popup_size"
+ android:layout_height="@dimen/container_fastscroll_popup_size"
+ android:textSize="@dimen/container_fastscroll_popup_text_size"
+ android:layout_below="@+id/search_container"
+ android:id="@+id/fast_scroller_popup"
+ android:elevation="3dp"
+ android:gravity="center"
+ android:alpha="0"
+ android:saveEnabled="false"
+ android:layout_gravity="top|end"
+ android:layout_marginEnd="@dimen/container_fastscroll_popup_margin"
+ android:textColor="@android:color/white" />
+
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 12e902ac3..7f778d6d4 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -54,6 +54,7 @@
<dimen name="container_fastscroll_thumb_min_width">5dp</dimen>
<dimen name="container_fastscroll_thumb_max_width">9dp</dimen>
+ <dimen name="container_fastscroll_popup_margin">18dp</dimen>
<dimen name="container_fastscroll_thumb_height">72dp</dimen>
<dimen name="container_fastscroll_thumb_touch_inset">-24dp</dimen>
<dimen name="container_fastscroll_popup_size">72dp</dimen>
diff --git a/src/com/android/launcher3/BaseRecyclerView.java b/src/com/android/launcher3/BaseRecyclerView.java
index 45bc94006..9bdbe2580 100644
--- a/src/com/android/launcher3/BaseRecyclerView.java
+++ b/src/com/android/launcher3/BaseRecyclerView.java
@@ -22,6 +22,8 @@ import android.graphics.Rect;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.MotionEvent;
+import android.view.ViewGroup;
+
import com.android.launcher3.util.Thunk;
@@ -41,7 +43,7 @@ public abstract class BaseRecyclerView extends RecyclerView
@Thunk int mDy = 0;
private float mDeltaThreshold;
- protected BaseRecyclerViewFastScrollBar mScrollbar;
+ protected final BaseRecyclerViewFastScrollBar mScrollbar;
private int mDownX;
private int mDownY;
@@ -92,6 +94,12 @@ public abstract class BaseRecyclerView extends RecyclerView
addOnItemTouchListener(this);
}
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ mScrollbar.setPopupView(((ViewGroup) getParent()).findViewById(R.id.fast_scroller_popup));
+ }
+
/**
* We intercept the touch handling only to support fast scrolling when initiated from the
* scroll bar. Otherwise, we fall back to the default RecyclerView touch handling.
@@ -235,7 +243,7 @@ public abstract class BaseRecyclerView extends RecyclerView
// Only show the scrollbar if there is height to be scrolled
int availableScrollBarHeight = getAvailableScrollBarHeight();
if (availableScrollHeight <= 0) {
- mScrollbar.setThumbOffset(-1, -1);
+ mScrollbar.setThumbOffsetY(-1);
return;
}
@@ -246,18 +254,7 @@ public abstract class BaseRecyclerView extends RecyclerView
(int) (((float) scrollY / availableScrollHeight) * availableScrollBarHeight);
// Calculate the position and size of the scroll bar
- mScrollbar.setThumbOffset(getScrollBarX(), scrollBarY);
- }
-
- /**
- * @return the x position for the scrollbar thumb
- */
- protected int getScrollBarX() {
- if (Utilities.isRtl(getResources())) {
- return mBackgroundPadding.left;
- } else {
- return getWidth() - mBackgroundPadding.right - mScrollbar.getThumbWidth();
- }
+ mScrollbar.setThumbOffsetY(scrollBarY);
}
/**
diff --git a/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java b/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java
index 3d71632ce..770166dae 100644
--- a/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java
+++ b/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java
@@ -15,21 +15,18 @@
*/
package com.android.launcher3;
-import android.animation.AnimatorSet;
-import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
-import android.graphics.Point;
import android.graphics.Rect;
+import android.util.Property;
import android.view.MotionEvent;
+import android.view.View;
import android.view.ViewConfiguration;
-
-import com.android.launcher3.util.Thunk;
+import android.widget.TextView;
/**
* The track and scrollbar that shows when you scroll the list.
@@ -40,29 +37,46 @@ public class BaseRecyclerViewFastScrollBar {
void setFastScrollFocusState(final FastBitmapDrawable.State focusState, boolean animated);
}
+ private static final Property<BaseRecyclerViewFastScrollBar, Integer> TRACK_WIDTH =
+ new Property<BaseRecyclerViewFastScrollBar, Integer>(Integer.class, "width") {
+
+ @Override
+ public Integer get(BaseRecyclerViewFastScrollBar scrollBar) {
+ return scrollBar.mWidth;
+ }
+
+ @Override
+ public void set(BaseRecyclerViewFastScrollBar scrollBar, Integer value) {
+ scrollBar.setTrackWidth(value);
+ }
+ };
+
private final static int MAX_TRACK_ALPHA = 30;
private final static int SCROLL_BAR_VIS_DURATION = 150;
+ private static final float FAST_SCROLL_OVERLAY_Y_OFFSET_FACTOR = 1.5f;
+
+ private final Rect mTmpRect = new Rect();
+ private final BaseRecyclerView mRv;
+
+ private final boolean mIsRtl;
- @Thunk BaseRecyclerView mRv;
- private BaseRecyclerViewFastScrollPopup mPopup;
-
- private AnimatorSet mScrollbarAnimator;
-
- private int mThumbInactiveColor;
- private int mThumbActiveColor;
- @Thunk Point mThumbOffset = new Point(-1, -1);
- @Thunk Paint mThumbPaint;
- private int mThumbMinWidth;
- private int mThumbMaxWidth;
- @Thunk int mThumbWidth;
- @Thunk int mThumbHeight;
- private int mThumbCurvature;
- private Path mThumbPath = new Path();
- private Paint mTrackPaint;
- private int mTrackWidth;
- private float mLastTouchY;
// The inset is the buffer around which a point will still register as a click on the scrollbar
- private int mTouchInset;
+ private final int mTouchInset;
+
+ private final int mMinWidth;
+ private final int mMaxWidth;
+
+ // Current width of the track
+ private int mWidth;
+ private ObjectAnimator mWidthAnimator;
+
+ private final Path mThumbPath = new Path();
+ private final Paint mThumbPaint;
+ private final int mThumbHeight;
+
+ private final Paint mTrackPaint;
+
+ private float mLastTouchY;
private boolean mIsDragging;
private boolean mIsThumbDetached;
private boolean mCanThumbDetach;
@@ -70,27 +84,35 @@ public class BaseRecyclerViewFastScrollBar {
// This is the offset from the top of the scrollbar when the user first starts touching. To
// prevent jumping, this offset is applied as the user scrolls.
- private int mTouchOffset;
+ private int mTouchOffsetY;
+ private int mThumbOffsetY;
- private Rect mInvalidateRect = new Rect();
- private Rect mTmpRect = new Rect();
+ // Fast scroller popup
+ private TextView mPopupView;
+ private boolean mPopupVisible;
+ private String mPopupSectionName;
public BaseRecyclerViewFastScrollBar(BaseRecyclerView rv, Resources res) {
mRv = rv;
- mPopup = new BaseRecyclerViewFastScrollPopup(rv, res);
mTrackPaint = new Paint();
mTrackPaint.setColor(rv.getFastScrollerTrackColor(Color.BLACK));
mTrackPaint.setAlpha(MAX_TRACK_ALPHA);
- mThumbActiveColor = mThumbInactiveColor = Utilities.getColorAccent(rv.getContext());
+
mThumbPaint = new Paint();
mThumbPaint.setAntiAlias(true);
- mThumbPaint.setColor(mThumbInactiveColor);
+ mThumbPaint.setColor(Utilities.getColorAccent(rv.getContext()));
mThumbPaint.setStyle(Paint.Style.FILL);
- mThumbWidth = mThumbMinWidth = res.getDimensionPixelSize(R.dimen.container_fastscroll_thumb_min_width);
- mThumbMaxWidth = res.getDimensionPixelSize(R.dimen.container_fastscroll_thumb_max_width);
+
+ mWidth = mMinWidth = res.getDimensionPixelSize(R.dimen.container_fastscroll_thumb_min_width);
+ mMaxWidth = res.getDimensionPixelSize(R.dimen.container_fastscroll_thumb_max_width);
mThumbHeight = res.getDimensionPixelSize(R.dimen.container_fastscroll_thumb_height);
- mThumbCurvature = mThumbMaxWidth - mThumbMinWidth;
mTouchInset = res.getDimensionPixelSize(R.dimen.container_fastscroll_thumb_touch_inset);
+ mIsRtl = Utilities.isRtl(res);
+ updateThumbPath();
+ }
+
+ public void setPopupView(View popup) {
+ mPopupView = (TextView) popup;
}
public void setDetachThumbOnFastScroll() {
@@ -101,51 +123,54 @@ public class BaseRecyclerViewFastScrollBar {
mIsThumbDetached = false;
}
- public void setThumbOffset(int x, int y) {
- if (mThumbOffset.x == x && mThumbOffset.y == y) {
+ private int getDrawLeft() {
+ return mIsRtl ? 0 : (mRv.getWidth() - mMaxWidth);
+ }
+
+ public void setThumbOffsetY(int y) {
+ if (mThumbOffsetY == y) {
return;
}
- mInvalidateRect.set(mThumbOffset.x - mThumbCurvature, mThumbOffset.y,
- mThumbOffset.x + mThumbWidth, mThumbOffset.y + mThumbHeight);
- mThumbOffset.set(x, y);
- updateThumbPath();
- mInvalidateRect.union(mThumbOffset.x - mThumbCurvature, mThumbOffset.y,
- mThumbOffset.x + mThumbWidth, mThumbOffset.y + mThumbHeight);
- mRv.invalidate(mInvalidateRect);
- }
- public Point getThumbOffset() {
- return mThumbOffset;
+ // Invalidate the previous and new thumb area
+ int drawLeft = getDrawLeft();
+ mTmpRect.set(drawLeft, mThumbOffsetY, drawLeft + mMaxWidth, mThumbOffsetY + mThumbHeight);
+ mThumbOffsetY = y;
+ mTmpRect.union(drawLeft, mThumbOffsetY, drawLeft + mMaxWidth, mThumbOffsetY + mThumbHeight);
+ mRv.invalidate(mTmpRect);
}
- // Setter/getter for the thumb bar width for animations
- public void setThumbWidth(int width) {
- mInvalidateRect.set(mThumbOffset.x - mThumbCurvature, mThumbOffset.y,
- mThumbOffset.x + mThumbWidth, mThumbOffset.y + mThumbHeight);
- mThumbWidth = width;
- updateThumbPath();
- mInvalidateRect.union(mThumbOffset.x - mThumbCurvature, mThumbOffset.y,
- mThumbOffset.x + mThumbWidth, mThumbOffset.y + mThumbHeight);
- mRv.invalidate(mInvalidateRect);
+ public int getThumbOffsetY() {
+ return mThumbOffsetY;
}
- public int getThumbWidth() {
- return mThumbWidth;
- }
+ private void setTrackWidth(int width) {
+ if (mWidth == width) {
+ return;
+ }
+ int left = getDrawLeft();
+ // Invalidate the whole scroll bar area.
+ mRv.invalidate(left, 0, left + mMaxWidth, mRv.getVisibleHeight());
- // Setter/getter for the track bar width for animations
- public void setTrackWidth(int width) {
- mInvalidateRect.set(mThumbOffset.x - mThumbCurvature, 0, mThumbOffset.x + mThumbWidth,
- mRv.getVisibleHeight());
- mTrackWidth = width;
+ mWidth = width;
updateThumbPath();
- mInvalidateRect.union(mThumbOffset.x - mThumbCurvature, 0, mThumbOffset.x + mThumbWidth,
- mRv.getVisibleHeight());
- mRv.invalidate(mInvalidateRect);
}
- public int getTrackWidth() {
- return mTrackWidth;
+ /**
+ * Updates the path for the thumb drawable.
+ */
+ private void updateThumbPath() {
+ int smallWidth = mIsRtl ? mWidth : -mWidth;
+ int largeWidth = mIsRtl ? mMaxWidth : -mMaxWidth;
+
+ mThumbPath.reset();
+ mThumbPath.moveTo(0, 0);
+ mThumbPath.lineTo(0, mThumbHeight); // Left edge
+ mThumbPath.lineTo(smallWidth, mThumbHeight); // bottom edge
+ mThumbPath.cubicTo(smallWidth, mThumbHeight, // right edge
+ largeWidth, mThumbHeight / 2,
+ smallWidth, 0);
+ mThumbPath.close();
}
public int getThumbHeight() {
@@ -153,7 +178,7 @@ public class BaseRecyclerViewFastScrollBar {
}
public int getThumbMaxWidth() {
- return mThumbMaxWidth;
+ return mMaxWidth;
}
public boolean isDraggingThumb() {
@@ -176,7 +201,7 @@ public class BaseRecyclerViewFastScrollBar {
switch (action) {
case MotionEvent.ACTION_DOWN:
if (isNearThumb(downX, downY)) {
- mTouchOffset = downY - mThumbOffset.y;
+ mTouchOffsetY = downY - mThumbOffsetY;
}
break;
case MotionEvent.ACTION_MOVE:
@@ -191,32 +216,35 @@ public class BaseRecyclerViewFastScrollBar {
if (mCanThumbDetach) {
mIsThumbDetached = true;
}
- mTouchOffset += (lastY - downY);
- mPopup.animateVisibility(true);
+ mTouchOffsetY += (lastY - downY);
+ animatePopupVisibility(true);
showActiveScrollbar(true);
}
if (mIsDragging) {
// Update the fastscroller section name at this touch position
int top = mRv.getBackgroundPadding().top;
int bottom = top + mRv.getVisibleHeight() - mThumbHeight;
- float boundedY = (float) Math.max(top, Math.min(bottom, y - mTouchOffset));
+ float boundedY = (float) Math.max(top, Math.min(bottom, y - mTouchOffsetY));
String sectionName = mRv.scrollToPositionAtProgress((boundedY - top) /
(bottom - top));
- mPopup.setSectionName(sectionName);
- mPopup.animateVisibility(!sectionName.isEmpty());
- mRv.invalidate(mPopup.updateFastScrollerBounds(lastY));
+ if (!sectionName.equals(mPopupSectionName)) {
+ mPopupSectionName = sectionName;
+ mPopupView.setText(sectionName);
+ }
+ animatePopupVisibility(!sectionName.isEmpty());
+ updatePopupY(lastY);
mLastTouchY = boundedY;
- setThumbOffset(mRv.getScrollBarX(), (int) mLastTouchY);
+ setThumbOffsetY((int) mLastTouchY);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
- mTouchOffset = 0;
+ mTouchOffsetY = 0;
mLastTouchY = 0;
mIgnoreDragGesture = false;
if (mIsDragging) {
mIsDragging = false;
- mPopup.animateVisibility(false);
+ animatePopupVisibility(false);
showActiveScrollbar(false);
}
break;
@@ -224,74 +252,58 @@ public class BaseRecyclerViewFastScrollBar {
}
public void draw(Canvas canvas) {
- if (mThumbOffset.x < 0 || mThumbOffset.y < 0) {
+ if (mThumbOffsetY < 0) {
return;
}
-
- // Draw the scroll bar track and thumb
- if (mTrackPaint.getAlpha() > 0) {
- canvas.drawRect(mThumbOffset.x, 0, mThumbOffset.x + mThumbWidth,
- mRv.getVisibleHeight(), mTrackPaint);
+ int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
+ if (!mIsRtl) {
+ canvas.translate(mRv.getWidth(), 0);
}
- canvas.drawPath(mThumbPath, mThumbPaint);
+ // Draw the track
+ int thumbWidth = mIsRtl ? mWidth : -mWidth;
+ canvas.drawRect(0, 0, thumbWidth, mRv.getVisibleHeight(), mTrackPaint);
- // Draw the popup
- mPopup.draw(canvas);
+ canvas.translate(0, mThumbOffsetY);
+ canvas.drawPath(mThumbPath, mThumbPaint);
+ canvas.restoreToCount(saveCount);
}
/**
- * Animates the width and color of the scrollbar.
+ * Animates the width of the scrollbar.
*/
private void showActiveScrollbar(boolean isScrolling) {
- if (mScrollbarAnimator != null) {
- mScrollbarAnimator.cancel();
- }
-
- mScrollbarAnimator = new AnimatorSet();
- ObjectAnimator trackWidthAnim = ObjectAnimator.ofInt(this, "trackWidth",
- isScrolling ? mThumbMaxWidth : mThumbMinWidth);
- ObjectAnimator thumbWidthAnim = ObjectAnimator.ofInt(this, "thumbWidth",
- isScrolling ? mThumbMaxWidth : mThumbMinWidth);
- mScrollbarAnimator.playTogether(trackWidthAnim, thumbWidthAnim);
- if (mThumbActiveColor != mThumbInactiveColor) {
- ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(),
- mThumbPaint.getColor(), isScrolling ? mThumbActiveColor : mThumbInactiveColor);
- colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animator) {
- mThumbPaint.setColor((Integer) animator.getAnimatedValue());
- mRv.invalidate(mThumbOffset.x, mThumbOffset.y, mThumbOffset.x + mThumbWidth,
- mThumbOffset.y + mThumbHeight);
- }
- });
- mScrollbarAnimator.play(colorAnimation);
+ if (mWidthAnimator != null) {
+ mWidthAnimator.cancel();
}
- mScrollbarAnimator.setDuration(SCROLL_BAR_VIS_DURATION);
- mScrollbarAnimator.start();
- }
- /**
- * Updates the path for the thumb drawable.
- */
- private void updateThumbPath() {
- mThumbCurvature = mThumbMaxWidth - mThumbWidth;
- mThumbPath.reset();
- mThumbPath.moveTo(mThumbOffset.x + mThumbWidth, mThumbOffset.y); // tr
- mThumbPath.lineTo(mThumbOffset.x + mThumbWidth, mThumbOffset.y + mThumbHeight); // br
- mThumbPath.lineTo(mThumbOffset.x, mThumbOffset.y + mThumbHeight); // bl
- mThumbPath.cubicTo(mThumbOffset.x, mThumbOffset.y + mThumbHeight,
- mThumbOffset.x - mThumbCurvature, mThumbOffset.y + mThumbHeight / 2,
- mThumbOffset.x, mThumbOffset.y); // bl2tl
- mThumbPath.close();
+ mWidthAnimator = ObjectAnimator.ofInt(this, TRACK_WIDTH,
+ isScrolling ? mMaxWidth : mMinWidth);
+ mWidthAnimator.setDuration(SCROLL_BAR_VIS_DURATION);
+ mWidthAnimator.start();
}
/**
* Returns whether the specified points are near the scroll bar bounds.
*/
public boolean isNearThumb(int x, int y) {
- mTmpRect.set(mThumbOffset.x, mThumbOffset.y, mThumbOffset.x + mThumbWidth,
- mThumbOffset.y + mThumbHeight);
+ int left = getDrawLeft();
+ mTmpRect.set(left, mThumbOffsetY, left + mMaxWidth, mThumbOffsetY + mThumbHeight);
mTmpRect.inset(mTouchInset, mTouchInset);
return mTmpRect.contains(x, y);
}
+
+ private void animatePopupVisibility(boolean visible) {
+ if (mPopupVisible != visible) {
+ mPopupVisible = visible;
+ mPopupView.animate().cancel();
+ mPopupView.animate().alpha(visible ? 1f : 0f).setDuration(visible ? 200 : 150).start();
+ }
+ }
+
+ private void updatePopupY(int lastTouchY) {
+ int height = mPopupView.getHeight();
+ float top = lastTouchY - (FAST_SCROLL_OVERLAY_Y_OFFSET_FACTOR * height);
+ top = Math.max(mMaxWidth, Math.min(top, mRv.getVisibleHeight() - mMaxWidth - height));
+ mPopupView.setTranslationY(top);
+ }
}
diff --git a/src/com/android/launcher3/BaseRecyclerViewFastScrollPopup.java b/src/com/android/launcher3/BaseRecyclerViewFastScrollPopup.java
deleted file mode 100644
index b9b044db9..000000000
--- a/src/com/android/launcher3/BaseRecyclerViewFastScrollPopup.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (C) 2015 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;
-
-import android.animation.Animator;
-import android.animation.ObjectAnimator;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-
-import com.android.launcher3.graphics.HolographicOutlineHelper;
-
-/**
- * The fast scroller popup that shows the section name the list will jump to.
- */
-public class BaseRecyclerViewFastScrollPopup {
-
- private static final float FAST_SCROLL_OVERLAY_Y_OFFSET_FACTOR = 1.5f;
-
- private static final int SHADOW_INSET = 3;
- private static final int SHADOW_SHIFT_Y = 2;
- private static final float SHADOW_ALPHA_MULTIPLIER = 0.67f;
-
- private Resources mRes;
- private BaseRecyclerView mRv;
-
- private Bitmap mShadow;
- private Paint mShadowPaint;
-
- private Drawable mBg;
- // The absolute bounds of the fast scroller bg
- private Rect mBgBounds = new Rect();
- private int mBgOriginalSize;
- private Rect mInvalidateRect = new Rect();
- private Rect mTmpRect = new Rect();
-
- private String mSectionName;
- private Paint mTextPaint;
- private Rect mTextBounds = new Rect();
- private float mAlpha;
-
- private Animator mAlphaAnimator;
- private boolean mVisible;
-
- public BaseRecyclerViewFastScrollPopup(BaseRecyclerView rv, Resources res) {
- mRes = res;
- mRv = rv;
-
- mBgOriginalSize = res.getDimensionPixelSize(R.dimen.container_fastscroll_popup_size);
- mBg = rv.getContext().getDrawable(R.drawable.container_fastscroll_popup_bg);
- mBg.setBounds(0, 0, mBgOriginalSize, mBgOriginalSize);
-
- mTextPaint = new Paint();
- mTextPaint.setColor(Color.WHITE);
- mTextPaint.setAntiAlias(true);
- mTextPaint.setTextSize(res.getDimensionPixelSize(R.dimen.container_fastscroll_popup_text_size));
-
- mShadowPaint = new Paint();
- mShadowPaint.setAntiAlias(true);
- mShadowPaint.setFilterBitmap(true);
- mShadowPaint.setDither(true);
- }
-
- /**
- * Sets the section name.
- */
- public void setSectionName(String sectionName) {
- if (!sectionName.equals(mSectionName)) {
- mSectionName = sectionName;
- mTextPaint.getTextBounds(sectionName, 0, sectionName.length(), mTextBounds);
- // Update the width to use measureText since that is more accurate
- mTextBounds.right = (int) (mTextBounds.left + mTextPaint.measureText(sectionName));
- }
- }
-
- /**
- * Updates the bounds for the fast scroller.
- *
- * @return the invalidation rect for this update.
- */
- public Rect updateFastScrollerBounds(int lastTouchY) {
- mInvalidateRect.set(mBgBounds);
-
- if (isVisible()) {
- // Calculate the dimensions and position of the fast scroller popup
- int edgePadding = mRv.getMaxScrollbarWidth();
- int bgPadding = (mBgOriginalSize - mTextBounds.height()) / 2;
- int bgHeight = mBgOriginalSize;
- int bgWidth = Math.max(mBgOriginalSize, mTextBounds.width() + (2 * bgPadding));
- if (Utilities.isRtl(mRes)) {
- mBgBounds.left = mRv.getBackgroundPadding().left + (2 * mRv.getMaxScrollbarWidth());
- mBgBounds.right = mBgBounds.left + bgWidth;
- } else {
- mBgBounds.right = mRv.getWidth() - mRv.getBackgroundPadding().right -
- (2 * mRv.getMaxScrollbarWidth());
- mBgBounds.left = mBgBounds.right - bgWidth;
- }
- mBgBounds.top = lastTouchY - (int) (FAST_SCROLL_OVERLAY_Y_OFFSET_FACTOR * bgHeight);
- mBgBounds.top = Math.max(edgePadding,
- Math.min(mBgBounds.top, mRv.getVisibleHeight() - edgePadding - bgHeight));
- mBgBounds.bottom = mBgBounds.top + bgHeight;
-
- // Generate a bitmap for a shadow matching these bounds
- mShadow = HolographicOutlineHelper.getInstance(
- mRv.getContext()).createMediumDropShadow(mBg, false /* shouldCache */);
- } else {
- mShadow = null;
- mBgBounds.setEmpty();
- }
-
- // Combine the old and new fast scroller bounds to create the full invalidate rect
- mInvalidateRect.union(mBgBounds);
- return mInvalidateRect;
- }
-
- /**
- * Animates the visibility of the fast scroller popup.
- */
- public void animateVisibility(boolean visible) {
- if (mVisible != visible) {
- mVisible = visible;
- if (mAlphaAnimator != null) {
- mAlphaAnimator.cancel();
- }
- mAlphaAnimator = ObjectAnimator.ofFloat(this, "alpha", visible ? 1f : 0f);
- mAlphaAnimator.setDuration(visible ? 200 : 150);
- mAlphaAnimator.start();
- }
- }
-
- // Setter/getter for the popup alpha for animations
- public void setAlpha(float alpha) {
- mAlpha = alpha;
- mRv.invalidate(mBgBounds);
- }
-
- public float getAlpha() {
- return mAlpha;
- }
-
- public int getHeight() {
- return mBgOriginalSize;
- }
-
- public void draw(Canvas c) {
- if (isVisible()) {
- // Determine the alpha and prepare the canvas
- final int alpha = (int) (mAlpha * 255);
- int restoreCount = c.save(Canvas.MATRIX_SAVE_FLAG);
- c.translate(mBgBounds.left, mBgBounds.top);
- mTmpRect.set(mBgBounds);
- mTmpRect.offsetTo(0, 0);
-
- // Expand the rect (with a negative inset), translate it, and draw the shadow
- if (mShadow != null) {
- mTmpRect.inset(-SHADOW_INSET * 2, -SHADOW_INSET * 2);
- mTmpRect.offset(0, SHADOW_SHIFT_Y);
- mShadowPaint.setAlpha((int) (alpha * SHADOW_ALPHA_MULTIPLIER));
- c.drawBitmap(mShadow, null, mTmpRect, mShadowPaint);
- mTmpRect.inset(SHADOW_INSET * 2, SHADOW_INSET * 2);
- mTmpRect.offset(0, -SHADOW_SHIFT_Y);
- }
-
- // Draw the background
- mBg.setBounds(mTmpRect);
- mBg.setAlpha(alpha);
- mBg.draw(c);
-
- // Draw the text
- mTextPaint.setAlpha(alpha);
- c.drawText(mSectionName, (mBgBounds.width() - mTextBounds.width()) / 2,
- mBgBounds.height() - (mBgBounds.height() / 2) - mTextBounds.exactCenterY(),
- mTextPaint);
- c.restoreToCount(restoreCount);
- }
- }
-
- public boolean isVisible() {
- return (mAlpha > 0f) && (mSectionName != null);
- }
-}
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 689ee3816..5c9e3f74e 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -272,7 +272,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
// IF scroller is at the very top OR there is no scroll bar because there is probably not
// enough items to scroll, THEN it's okay for the container to be pulled down.
- if (mAppsRecyclerView.getScrollBar().getThumbOffset().y <= 0) {
+ if (mAppsRecyclerView.getScrollBar().getThumbOffsetY() <= 0) {
return true;
}
return false;
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 0173847e0..5a9ea6bb3 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -299,14 +299,14 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
// Skip early if there are no items or we haven't been measured
if (items.isEmpty() || mNumAppsPerRow == 0) {
- mScrollbar.setThumbOffset(-1, -1);
+ mScrollbar.setThumbOffsetY(-1);
return;
}
// Skip early if, there no child laid out in the container.
int scrollY = getCurrentScrollY();
if (scrollY < 0) {
- mScrollbar.setThumbOffset(-1, -1);
+ mScrollbar.setThumbOffsetY(-1);
return;
}
@@ -314,7 +314,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
int availableScrollBarHeight = getAvailableScrollBarHeight();
int availableScrollHeight = getAvailableScrollHeight();
if (availableScrollHeight <= 0) {
- mScrollbar.setThumbOffset(-1, -1);
+ mScrollbar.setThumbOffsetY(-1);
return;
}
@@ -323,11 +323,10 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
// Calculate the current scroll position, the scrollY of the recycler view accounts
// for the view padding, while the scrollBarY is drawn right up to the background
// padding (ignoring padding)
- int scrollBarX = getScrollBarX();
int scrollBarY = mBackgroundPadding.top +
(int) (((float) scrollY / availableScrollHeight) * availableScrollBarHeight);
- int thumbScrollY = mScrollbar.getThumbOffset().y;
+ int thumbScrollY = mScrollbar.getThumbOffsetY();
int diffScrollY = scrollBarY - thumbScrollY;
if (diffScrollY * dy > 0f) {
// User is scrolling in the same direction the thumb needs to catch up to the
@@ -344,7 +343,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
thumbScrollY += Math.min(offset, diffScrollY);
}
thumbScrollY = Math.max(0, Math.min(availableScrollBarHeight, thumbScrollY));
- mScrollbar.setThumbOffset(scrollBarX, thumbScrollY);
+ mScrollbar.setThumbOffsetY(thumbScrollY);
if (scrollBarY == thumbScrollY) {
mScrollbar.reattachThumbToScroll();
}
@@ -352,7 +351,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
// User is scrolling in an opposite direction to the direction that the thumb
// needs to catch up to the scroll position. Do nothing except for updating
// the scroll bar x to match the thumb width.
- mScrollbar.setThumbOffset(scrollBarX, thumbScrollY);
+ mScrollbar.setThumbOffsetY(thumbScrollY);
}
}
} else {
diff --git a/src/com/android/launcher3/graphics/HolographicOutlineHelper.java b/src/com/android/launcher3/graphics/HolographicOutlineHelper.java
index 0d70bdee1..9c397210e 100644
--- a/src/com/android/launcher3/graphics/HolographicOutlineHelper.java
+++ b/src/com/android/launcher3/graphics/HolographicOutlineHelper.java
@@ -158,18 +158,13 @@ public class HolographicOutlineHelper {
}
public Bitmap createMediumDropShadow(BubbleTextView view) {
- return createMediumDropShadow(view.getIcon(), view.getScaleX(), view.getScaleY(), true);
- }
-
- public Bitmap createMediumDropShadow(Drawable drawable, boolean shouldCache) {
- return createMediumDropShadow(drawable, 1f, 1f, shouldCache);
- }
-
- Bitmap createMediumDropShadow(Drawable drawable, float scaleX, float scaleY,
- boolean shouldCache) {
+ Drawable drawable = view.getIcon();
if (drawable == null) {
return null;
}
+
+ float scaleX = view.getScaleX();
+ float scaleY = view.getScaleY();
Rect rect = drawable.getBounds();
int bitmapWidth = (int) (rect.width() * scaleX);
@@ -179,14 +174,11 @@ public class HolographicOutlineHelper {
}
int key = (bitmapWidth << 16) | bitmapHeight;
- Bitmap cache = shouldCache ? mBitmapCache.get(key) : null;
+ Bitmap cache = mBitmapCache.get(key);
if (cache == null) {
cache = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ALPHA_8);
mCanvas.setBitmap(cache);
-
- if (shouldCache) {
- mBitmapCache.put(key, cache);
- }
+ mBitmapCache.put(key, cache);
} else {
mCanvas.setBitmap(cache);
mCanvas.drawColor(Color.BLACK, PorterDuff.Mode.CLEAR);
@@ -206,7 +198,7 @@ public class HolographicOutlineHelper {
int resultWidth = bitmapWidth + extraSize;
int resultHeight = bitmapHeight + extraSize;
key = (resultWidth << 16) | resultHeight;
- Bitmap result = shouldCache ? mBitmapCache.get(key) : null;
+ Bitmap result = mBitmapCache.get(key);
if (result == null) {
result = Bitmap.createBitmap(resultWidth, resultHeight, Bitmap.Config.ALPHA_8);
mCanvas.setBitmap(result);
diff --git a/src/com/android/launcher3/widget/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/WidgetsRecyclerView.java
index 2560661c1..c33978eea 100644
--- a/src/com/android/launcher3/widget/WidgetsRecyclerView.java
+++ b/src/com/android/launcher3/widget/WidgetsRecyclerView.java
@@ -121,7 +121,7 @@ public class WidgetsRecyclerView extends BaseRecyclerView {
// Skip early if, there no child laid out in the container.
int scrollY = getCurrentScrollY();
if (scrollY < 0) {
- mScrollbar.setThumbOffset(-1, -1);
+ mScrollbar.setThumbOffsetY(-1);
return;
}