summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Lee <llee@cyngn.com>2015-04-02 15:53:26 -0700
committerRajesh Yengisetty <rajesh@cyngn.com>2015-04-16 21:47:37 +0000
commitbdee9dd24e9bc46176463018881433a4715a0a7c (patch)
tree78de5c21dc2a79041ac4655424b05d3852f3d25b
parent60046217f7508a70f0b83a2fcba551f75fc67f2c (diff)
downloadandroid_packages_apps_Trebuchet-bdee9dd24e9bc46176463018881433a4715a0a7c.tar.gz
android_packages_apps_Trebuchet-bdee9dd24e9bc46176463018881433a4715a0a7c.tar.bz2
android_packages_apps_Trebuchet-bdee9dd24e9bc46176463018881433a4715a0a7c.zip
AppDrawer: Add highlighting scrubbing and offset
When you drag the scrubber it now highlights that section differently Also when you drag on the scrubber, instead of bringing the section into view at any point, it will try to make it the 3 row from the bottom Change-Id: I7cefaa24fb3c757f6e031247bb4a247473dde828 (cherry picked from commit 0ce1d70dffb2f19a8e2997f03556b46b44c57156)
-rw-r--r--res/layout/app_drawer_item.xml11
-rw-r--r--src/com/android/launcher3/AppDrawerListAdapter.java122
-rw-r--r--src/com/android/launcher3/AppDrawerScrubber.java41
3 files changed, 144 insertions, 30 deletions
diff --git a/res/layout/app_drawer_item.xml b/res/layout/app_drawer_item.xml
index 43e2562ae..ac63b7c01 100644
--- a/res/layout/app_drawer_item.xml
+++ b/res/layout/app_drawer_item.xml
@@ -19,6 +19,15 @@
android:splitMotionEvents="false"
android:layout_width="match_parent"
android:layout_height="wrap_content">
+ <View
+ android:id="@+id/fading_background_back"
+ android:alpha="0"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:layout_alignTop="@+id/drawer_item_flow"
+ android:layout_alignBottom="@+id/drawer_item_flow"
+ android:background="@color/app_drawer_drag_background" />
+
<!-- Layout in back to front render order -->
<LinearLayout
android:id="@+id/drawer_item_flow"
@@ -30,7 +39,7 @@
android:orientation="horizontal" />
<View
- android:id="@+id/fading_background"
+ android:id="@+id/fading_background_front"
android:alpha="0"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
diff --git a/src/com/android/launcher3/AppDrawerListAdapter.java b/src/com/android/launcher3/AppDrawerListAdapter.java
index ea3243534..22ff8e188 100644
--- a/src/com/android/launcher3/AppDrawerListAdapter.java
+++ b/src/com/android/launcher3/AppDrawerListAdapter.java
@@ -16,6 +16,8 @@
package com.android.launcher3;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.ComponentName;
import android.content.Context;
@@ -51,12 +53,27 @@ public class AppDrawerListAdapter extends RecyclerView.Adapter<AppDrawerListAdap
private static final String NUMERIC_OR_SPECIAL_HEADER = "#";
+ /**
+ * Tracks both the section index and the positional item index for the sections
+ * section: 0 0 0 1 1 2 3 4 4
+ * itemIndex: 0 1 2 3 4 5 6 7 8
+ * Sections: A A A B B C D E E
+ */
+ private static class SectionIndices {
+ public int mSectionIndex;
+ public int mItemIndex;
+ public SectionIndices(int sectionIndex, int itemIndex) {
+ mSectionIndex = sectionIndex;
+ mItemIndex = itemIndex;
+ }
+ }
+
private ArrayList<AppItemIndexedInfo> mHeaderList;
private LayoutInflater mLayoutInflater;
private Launcher mLauncher;
private DeviceProfile mDeviceProfile;
- private LinkedHashMap<String, Integer> mSectionHeaders;
+ private LinkedHashMap<String, SectionIndices> mSectionHeaders;
private LinearLayout.LayoutParams mIconParams;
private Rect mIconRect;
private LocaleSetManager mLocaleSetManager;
@@ -93,12 +110,14 @@ public class AppDrawerListAdapter extends RecyclerView.Adapter<AppDrawerListAdap
public static class ViewHolder extends RecyclerView.ViewHolder {
public AutoFitTextView mTextView;
public ViewGroup mLayout;
- public View mFadingBackground;
+ public View mFadingBackgroundFront;
+ public View mFadingBackgroundBack;
public ViewHolder(View itemView) {
super(itemView);
mTextView = (AutoFitTextView) itemView.findViewById(R.id.drawer_item_title);
mLayout = (ViewGroup) itemView.findViewById(R.id.drawer_item_flow);
- mFadingBackground = itemView.findViewById(R.id.fading_background);
+ mFadingBackgroundFront = itemView.findViewById(R.id.fading_background_front);
+ mFadingBackgroundBack = itemView.findViewById(R.id.fading_background_back);
}
}
@@ -111,6 +130,7 @@ public class AppDrawerListAdapter extends RecyclerView.Adapter<AppDrawerListAdap
private static final float MAX_SCALE = 2f;
private static final float MIN_SCALE = 1f;
private static final float FAST_SCROLL = 0.3f;
+ private static final int NO_SECTION_TARGET = -1;
private final float YDPI;
private final HashSet<ViewHolder> mViewHolderSet;
@@ -125,11 +145,16 @@ public class AppDrawerListAdapter extends RecyclerView.Adapter<AppDrawerListAdap
private float mFastScrollSpeed;
private float mLastScrollSpeed;
+ // If the user is scrubbing, we want to highlight the target section differently,
+ // so we use this to track where the user is currently scrubbing to
+ private int mSectionTarget;
+
public ItemAnimatorSet(Context ctx) {
mDragging = false;
mExpanding = false;
mPendingShrink = false;
mScrollState = RecyclerView.SCROLL_STATE_IDLE;
+ mSectionTarget = NO_SECTION_TARGET;
mViewHolderSet = new HashSet<>();
mInterpolator = new DecelerateInterpolator();
YDPI = ctx.getResources().getDisplayMetrics().ydpi;
@@ -161,6 +186,12 @@ public class AppDrawerListAdapter extends RecyclerView.Adapter<AppDrawerListAdap
mScrollState = newState;
mFastScrollSpeed = 0;
checkAnimationState();
+
+ // If the user is dragging, clear the section target
+ if (mScrollState == RecyclerView.SCROLL_STATE_DRAGGING
+ && mSectionTarget != NO_SECTION_TARGET) {
+ setSectionTarget(NO_SECTION_TARGET);
+ }
}
}
@@ -211,18 +242,46 @@ public class AppDrawerListAdapter extends RecyclerView.Adapter<AppDrawerListAdap
}
}
- public void createAnimationHook(ViewHolder holder) {
+ public void createAnimationHook(final ViewHolder holder) {
holder.mTextView.animate().cancel();
holder.mTextView.animate()
.setUpdateListener(new ItemAnimator(holder, mItemAnimatorSet))
+ .setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(final Animator animation) {
+ animateEnd(holder, animation);
+ }
+ })
.setDuration(ANIMATION_DURATION)
.start();
}
- public void animate(ViewHolder holder, ValueAnimator animation) {
+ public void animateEnd(ViewHolder holder, Animator animation) {
+ animate(holder, animation, 1f);
+ }
+
+ public void animate(ViewHolder holder, Animator animation) {
long diffTime = System.currentTimeMillis() - mStartTime;
float percentage = Math.min(diffTime / (float) ANIMATION_DURATION, 1f);
+
+ animate(holder, animation, percentage);
+
+ if (diffTime >= ANIMATION_DURATION) {
+ if (animation != null) {
+ animation.cancel();
+ }
+
+ if (mPendingShrink) {
+ mPendingShrink = false;
+ mLastScrollSpeed = 0;
+ checkAnimationState();
+ }
+
+ }
+ }
+
+ public void animate(ViewHolder holder, Animator animation, float percentage) {
percentage = mInterpolator.getInterpolation(percentage);
if (!mExpanding) {
@@ -233,17 +292,24 @@ public class AppDrawerListAdapter extends RecyclerView.Adapter<AppDrawerListAdap
holder.mTextView.setScaleX(targetScale);
holder.mTextView.setScaleY(targetScale);
- holder.mFadingBackground.setAlpha(percentage);
-
- if (diffTime >= ANIMATION_DURATION) {
- animation.cancel();
-
- if (mPendingShrink) {
- mPendingShrink = false;
- mLastScrollSpeed = 0;
- checkAnimationState();
- }
+ if (getSectionForPosition(holder.getPosition()) == mSectionTarget) {
+ holder.mFadingBackgroundFront.setVisibility(View.INVISIBLE);
+ holder.mFadingBackgroundBack.setAlpha(percentage);
+ holder.mFadingBackgroundBack.setVisibility(View.VISIBLE);
+ } else {
+ holder.mFadingBackgroundFront.setAlpha(percentage);
+ holder.mFadingBackgroundFront.setVisibility(View.VISIBLE);
+ holder.mFadingBackgroundBack.setVisibility(View.INVISIBLE);
+ }
+ }
+ /**
+ * Sets the section index to highlight different from the rest when scrubbing
+ */
+ public void setSectionTarget(int sectionIndex) {
+ mSectionTarget = sectionIndex;
+ for (ViewHolder holder : mViewHolderSet) {
+ animate(holder, null);
}
}
}
@@ -289,6 +355,13 @@ public class AppDrawerListAdapter extends RecyclerView.Adapter<AppDrawerListAdap
mItemAnimatorSet.setDragging(dragging);
}
+ /**
+ * Sets the section index to highlight different from the rest when scrubbing
+ */
+ public void setSectionTarget(int sectionIndex) {
+ mItemAnimatorSet.setSectionTarget(sectionIndex);
+ }
+
private void initParams() {
mDeviceProfile = LauncherAppState.getInstance().getDynamicGrid().getDeviceProfile();
@@ -380,18 +453,15 @@ public class AppDrawerListAdapter extends RecyclerView.Adapter<AppDrawerListAdap
private void populateSectionHeaders() {
if (mSectionHeaders == null || mSectionHeaders.size() != mHeaderList.size()) {
- mSectionHeaders = new LinkedHashMap<String, Integer>();
+ mSectionHeaders = new LinkedHashMap<>();
}
- int count = 0;
+
+ int sectionIndex = 0;
for (int i = 0; i < mHeaderList.size(); i++) {
- AppItemIndexedInfo info = mHeaderList.get(i);
if (!mHeaderList.get(i).isChild) {
- mSectionHeaders.put(String.valueOf(mHeaderList.get(i).mStartString), count);
- }
- if (info.mInfo.size() < mDeviceProfile.numColumnsBase) {
- count++;
- } else {
- count += info.mInfo.size() / mDeviceProfile.numColumnsBase;
+ mSectionHeaders.put(String.valueOf(mHeaderList.get(i).mStartString),
+ new SectionIndices(sectionIndex, i));
+ sectionIndex++;
}
}
}
@@ -741,12 +811,12 @@ public class AppDrawerListAdapter extends RecyclerView.Adapter<AppDrawerListAdap
@Override
public int getPositionForSection(int sectionIndex) {
- return mSectionHeaders.get(getSections()[sectionIndex]);
+ return mSectionHeaders.get(getSections()[sectionIndex]).mItemIndex;
}
@Override
public int getSectionForPosition(int position) {
- return mSectionHeaders.get(mHeaderList.get(position).mStartString);
+ return mSectionHeaders.get(mHeaderList.get(position).mStartString).mSectionIndex;
}
private void filterProtectedApps(ArrayList<AppInfo> list) {
diff --git a/src/com/android/launcher3/AppDrawerScrubber.java b/src/com/android/launcher3/AppDrawerScrubber.java
index 1670934d6..cafd00a18 100644
--- a/src/com/android/launcher3/AppDrawerScrubber.java
+++ b/src/com/android/launcher3/AppDrawerScrubber.java
@@ -20,9 +20,11 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.graphics.Color;
+import android.graphics.PointF;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.LinearSmoothScroller;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.LayoutInflater;
@@ -256,8 +258,41 @@ public class AppDrawerScrubber extends LinearLayout {
// get the index of the underlying list
int adapterIndex = mSectionContainer.getAdapterIndex(mLastIndex, index);
- mLayoutManager.smoothScrollToPosition(mListView, null,
- mAdapter.getPositionForSection(adapterIndex));
+ int itemIndex = mAdapter.getPositionForSection(adapterIndex);
+
+ // get any child's height since all children are the same height
+ int itemHeight = 0;
+ View child = mLayoutManager.getChildAt(0);
+ if (child != null) {
+ itemHeight = child.getMeasuredHeight();
+ }
+
+ if (itemHeight != 0) {
+ // scroll to the item such that there are 2 rows beneath it from the bottom
+ final int itemDiff = 2 * itemHeight;
+ LinearSmoothScroller scroller = new LinearSmoothScroller(mListView.getContext()) {
+ @Override
+ protected int getVerticalSnapPreference() {
+ // position the item against the end of the list view
+ return SNAP_TO_END;
+ }
+
+ @Override
+ public PointF computeScrollVectorForPosition(int targetPosition) {
+ return mLayoutManager.computeScrollVectorForPosition(targetPosition);
+ }
+
+ @Override
+ public int calculateDyToMakeVisible(View view, int snapPreference) {
+ int dy = super.calculateDyToMakeVisible(view, snapPreference);
+ return dy - itemDiff;
+ }
+ };
+ scroller.setTargetPosition(itemIndex);
+ mLayoutManager.startSmoothScroll(scroller);
+ }
+
+ mAdapter.setSectionTarget(adapterIndex);
mLastIndex = index;
}
@@ -272,4 +307,4 @@ public class AppDrawerScrubber extends LinearLayout {
touchTrack(false);
}
}
-} \ No newline at end of file
+}