Merge "Consistent scrolling experience for All apps and widget tray" into ub-launcher3-burnaby

This commit is contained in:
Hyunyoung Song
2015-06-04 18:39:44 +00:00
committed by Android (Google) Code Review
7 changed files with 88 additions and 24 deletions
-1
View File
@@ -39,7 +39,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@drawable/quantum_panel_dark" android:background="@drawable/quantum_panel_dark"
android:scrollbars="vertical"
android:elevation="15dp" android:elevation="15dp"
android:visibility="gone" /> android:visibility="gone" />
-1
View File
@@ -61,7 +61,6 @@
<dimen name="all_apps_prediction_icon_top_bottom_padding">12dp</dimen> <dimen name="all_apps_prediction_icon_top_bottom_padding">12dp</dimen>
<dimen name="all_apps_fast_scroll_bar_width">4dp</dimen> <dimen name="all_apps_fast_scroll_bar_width">4dp</dimen>
<dimen name="all_apps_fast_scroll_bar_min_height">64dp</dimen>
<dimen name="all_apps_fast_scroll_scrubber_touch_inset">-16dp</dimen> <dimen name="all_apps_fast_scroll_scrubber_touch_inset">-16dp</dimen>
<dimen name="all_apps_fast_scroll_popup_size">72dp</dimen> <dimen name="all_apps_fast_scroll_popup_size">72dp</dimen>
<dimen name="all_apps_fast_scroll_text_size">48dp</dimen> <dimen name="all_apps_fast_scroll_text_size">48dp</dimen>
@@ -86,10 +86,8 @@ public class BaseRecyclerView extends RecyclerView
private int mDownX; private int mDownX;
private int mDownY; private int mDownY;
private int mLastX;
private int mLastY; private int mLastY;
private int mScrollbarWidth; private int mScrollbarWidth;
private int mScrollbarMinHeight;
private int mScrollbarInset; private int mScrollbarInset;
private Rect mBackgroundPadding = new Rect(); private Rect mBackgroundPadding = new Rect();
@@ -121,8 +119,6 @@ public class BaseRecyclerView extends RecyclerView
mFastScrollTextPaint.setTextSize(res.getDimensionPixelSize( mFastScrollTextPaint.setTextSize(res.getDimensionPixelSize(
R.dimen.all_apps_fast_scroll_text_size)); R.dimen.all_apps_fast_scroll_text_size));
mScrollbarWidth = res.getDimensionPixelSize(R.dimen.all_apps_fast_scroll_bar_width); mScrollbarWidth = res.getDimensionPixelSize(R.dimen.all_apps_fast_scroll_bar_width);
mScrollbarMinHeight =
res.getDimensionPixelSize(R.dimen.all_apps_fast_scroll_bar_min_height);
mScrollbarInset = mScrollbarInset =
res.getDimensionPixelSize(R.dimen.all_apps_fast_scroll_scrubber_touch_inset); res.getDimensionPixelSize(R.dimen.all_apps_fast_scroll_scrubber_touch_inset);
setFastScrollerAlpha(mFastScrollAlpha); setFastScrollerAlpha(mFastScrollAlpha);
@@ -173,7 +169,7 @@ public class BaseRecyclerView extends RecyclerView
switch (action) { switch (action) {
case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_DOWN:
// Keep track of the down positions // Keep track of the down positions
mDownX = mLastX = x; mDownX = x;
mDownY = mLastY = y; mDownY = mLastY = y;
if (shouldStopScroll(ev)) { if (shouldStopScroll(ev)) {
stopScroll(); stopScroll();
@@ -188,7 +184,6 @@ public class BaseRecyclerView extends RecyclerView
animateFastScrollerVisibility(true); animateFastScrollerVisibility(true);
} }
if (mDraggingFastScroller) { if (mDraggingFastScroller) {
mLastX = x;
mLastY = y; mLastY = y;
// Scroll to the right position, and update the section name // Scroll to the right position, and update the section name
@@ -16,7 +16,6 @@
package com.android.launcher3.model; package com.android.launcher3.model;
import android.content.ComponentName;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import com.android.launcher3.ItemInfo; import com.android.launcher3.ItemInfo;
@@ -27,7 +26,6 @@ import java.util.Arrays;
* Represents a {@link Package} in the widget tray section. * Represents a {@link Package} in the widget tray section.
*/ */
public class PackageItemInfo extends ItemInfo { public class PackageItemInfo extends ItemInfo {
private static final String TAG = "PackageInfo";
/** /**
* A bitmap version of the application icon. * A bitmap version of the application icon.
@@ -35,12 +33,21 @@ public class PackageItemInfo extends ItemInfo {
public Bitmap iconBitmap; public Bitmap iconBitmap;
/** /**
* Indicates whether we're using a low res icon * Indicates whether we're using a low res icon.
*/ */
public boolean usingLowResIcon; public boolean usingLowResIcon;
/**
* Package name of the {@link ItemInfo}.
*/
public String packageName; public String packageName;
/**
* Character that is used as a section name for the {@link ItemInfo#title}.
* (e.g., "G" will be stored if title is "Google")
*/
public String titleSectionName;
int flags = 0; int flags = 0;
PackageItemInfo(String packageName) { PackageItemInfo(String packageName) {
@@ -10,6 +10,7 @@ import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetProviderInfo; import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.Utilities; import com.android.launcher3.Utilities;
import com.android.launcher3.compat.AlphabeticIndexCompat;
import com.android.launcher3.compat.UserHandleCompat; import com.android.launcher3.compat.UserHandleCompat;
import java.util.ArrayList; import java.util.ArrayList;
@@ -39,11 +40,13 @@ public class WidgetsModel {
private final Comparator mWidgetAndShortcutNameComparator; private final Comparator mWidgetAndShortcutNameComparator;
private final Comparator mAppNameComparator; private final Comparator mAppNameComparator;
private final IconCache mIconCache; private final IconCache mIconCache;
private AlphabeticIndexCompat mIndexer;
public WidgetsModel(Context context) { public WidgetsModel(Context context) {
mWidgetAndShortcutNameComparator = new WidgetsAndShortcutNameComparator(context); mWidgetAndShortcutNameComparator = new WidgetsAndShortcutNameComparator(context);
mAppNameComparator = (new AppNameComparator(context)).getAppInfoComparator(); mAppNameComparator = (new AppNameComparator(context)).getAppInfoComparator();
mIconCache = LauncherAppState.getInstance().getIconCache(); mIconCache = LauncherAppState.getInstance().getIconCache();
mIndexer = new AlphabeticIndexCompat(context);
} }
private WidgetsModel(WidgetsModel model) { private WidgetsModel(WidgetsModel model) {
@@ -62,6 +65,9 @@ public class WidgetsModel {
// Access methods that may be deleted if the private fields are made package-private. // Access methods that may be deleted if the private fields are made package-private.
public PackageItemInfo getPackageItemInfo(int pos) { public PackageItemInfo getPackageItemInfo(int pos) {
if (pos >= mPackageItemInfos.size() || pos < 0) {
return null;
}
return mPackageItemInfos.get(pos); return mPackageItemInfos.get(pos);
} }
@@ -112,6 +118,7 @@ public class WidgetsModel {
pInfo = new PackageItemInfo(packageName); pInfo = new PackageItemInfo(packageName);
mIconCache.getTitleAndIconForApp(packageName, UserHandleCompat.myUserHandle(), mIconCache.getTitleAndIconForApp(packageName, UserHandleCompat.myUserHandle(),
true /* userLowResIcon */, pInfo); true /* userLowResIcon */, pInfo);
pInfo.titleSectionName = mIndexer.computeSectionName(pInfo.title);
mWidgetsList.put(pInfo, widgetsShortcutsList); mWidgetsList.put(pInfo, widgetsShortcutsList);
tmpPackageItemInfos.put(packageName, pInfo); tmpPackageItemInfos.put(packageName, pInfo);
mPackageItemInfos.add(pInfo); mPackageItemInfos.add(pInfo);
@@ -20,8 +20,8 @@ import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.InsetDrawable;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.State; import android.support.v7.widget.RecyclerView.State;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
@@ -93,7 +93,6 @@ public class WidgetsContainerView extends BaseContainerView
mWidgetHostViewLoader = new WidgetHostViewLoader(mLauncher); mWidgetHostViewLoader = new WidgetHostViewLoader(mLauncher);
mAdapter = new WidgetsListAdapter(context, this, this, mLauncher); mAdapter = new WidgetsListAdapter(context, this, this, mLauncher);
mIconCache = (LauncherAppState.getInstance()).getIconCache(); mIconCache = (LauncherAppState.getInstance()).getIconCache();
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "WidgetsContainerView constructor"); Log.d(TAG, "WidgetsContainerView constructor");
} }
@@ -347,6 +346,23 @@ public class WidgetsContainerView extends BaseContainerView
setPadding(mFixedBounds.left, mFixedBounds.top, getMeasuredWidth() - mFixedBounds.right, setPadding(mFixedBounds.left, mFixedBounds.top, getMeasuredWidth() - mFixedBounds.right,
mFixedBounds.bottom); mFixedBounds.bottom);
} }
int inset = mFixedBounds.isEmpty() ? mView.getScrollbarWidth() : mFixedBoundsContainerInset;
mView.setPadding(inset + mView.getScrollbarWidth(), inset,
inset, inset);
}
@Override
protected void onUpdateBackgrounds() {
InsetDrawable background;
// Update the background of the reveal view and list to be inset with the fixed bound
// insets instead of the default insets
// TODO: Use quantum_panel instead of quantum_panel_shape.
int inset = mFixedBounds.isEmpty() ? mView.getScrollbarWidth() : mFixedBoundsContainerInset;
background = new InsetDrawable(
getContext().getResources().getDrawable(R.drawable.quantum_panel_shape),
inset, 0, inset, 0);
mView.updateBackgroundPadding(background);
} }
/** /**
@@ -19,20 +19,25 @@ package com.android.launcher3.widget;
import android.content.Context; import android.content.Context;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.LinearLayoutManager;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.MotionEvent; import android.view.View;
import com.android.launcher3.BaseRecyclerView; import com.android.launcher3.BaseRecyclerView;
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.AlphabeticIndexCompat;
import com.android.launcher3.model.WidgetsModel; import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.model.PackageItemInfo;
/** /**
* The widgets recycler view. * The widgets recycler view.
*/ */
public class WidgetsRecyclerView extends BaseRecyclerView { public class WidgetsRecyclerView extends BaseRecyclerView {
private static final String TAG = "WidgetsRecyclerView";
private WidgetsModel mWidgets; private WidgetsModel mWidgets;
private Rect mBackgroundPadding = new Rect(); private Rect mBackgroundPadding = new Rect();
private PackageItemInfo mLastPackageItemInfo;
public WidgetsRecyclerView(Context context) { public WidgetsRecyclerView(Context context) {
this(context, null); this(context, null);
@@ -68,8 +73,17 @@ public class WidgetsRecyclerView extends BaseRecyclerView {
*/ */
@Override @Override
public String scrollToPositionAtProgress(float touchFraction) { public String scrollToPositionAtProgress(float touchFraction) {
// Ensure that we have any sections float pos = mWidgets.getPackageSize() * touchFraction;
return "";
int posInt = (int) pos;
LinearLayoutManager layoutManager = ((LinearLayoutManager) getLayoutManager());
getCurScrollState(scrollPosState);
layoutManager.scrollToPositionWithOffset((int) pos,
(int) (scrollPosState.rowHeight * ((float) posInt - pos)));
posInt = (int) ((touchFraction == 1)? pos -1 : pos);
PackageItemInfo p = mWidgets.getPackageItemInfo(posInt);
return p.titleSectionName;
} }
/** /**
@@ -78,19 +92,41 @@ public class WidgetsRecyclerView extends BaseRecyclerView {
@Override @Override
public void updateVerticalScrollbarBounds() { public void updateVerticalScrollbarBounds() {
int rowCount = mWidgets.getPackageSize(); int rowCount = mWidgets.getPackageSize();
verticalScrollbarBounds.setEmpty();
// Skip early if there are no items. // Skip early if, there are no items.
if (rowCount == 0) { if (rowCount == 0) {
return;
}
// Skip early if, there no child laid out in the container.
getCurScrollState(scrollPosState);
if (scrollPosState.rowIndex < 0) {
return;
}
int actualHeight = getHeight() - getPaddingTop() - getPaddingBottom();
int totalScrollHeight = rowCount * scrollPosState.rowHeight;
// Skip early if the height of all the rows are actually less than the container height.
if (totalScrollHeight < actualHeight) {
verticalScrollbarBounds.setEmpty(); verticalScrollbarBounds.setEmpty();
return; return;
} }
int x, y; int scrollbarHeight = (int) (actualHeight / ((float) totalScrollHeight / actualHeight));
getCurScrollState(scrollPosState); int availableY = totalScrollHeight - actualHeight;
if (scrollPosState.rowIndex < 0) { int availableScrollY = actualHeight - scrollbarHeight;
verticalScrollbarBounds.setEmpty(); int y = (scrollPosState.rowIndex * scrollPosState.rowHeight)
- scrollPosState.rowTopOffset;
y = getPaddingTop() +
(int) (((float) (getPaddingTop() + y) / availableY) * availableScrollY);
// Calculate the position and size of the scroll bar.
int x = getWidth() - getScrollbarWidth() - mBackgroundPadding.right;
if (Utilities.isRtl(getResources())) {
x = mBackgroundPadding.left;
} }
// TODO verticalScrollbarBounds.set(x, y, x + getScrollbarWidth(), y + scrollbarHeight);
} }
/** /**
@@ -107,6 +143,11 @@ public class WidgetsRecyclerView extends BaseRecyclerView {
if (rowCount == 0) { if (rowCount == 0) {
return; return;
} }
// TODO View child = getChildAt(0);
int position = getChildPosition(child);
stateOut.rowIndex = position;
stateOut.rowTopOffset = getLayoutManager().getDecoratedTop(child);
stateOut.rowHeight = child.getHeight();
} }
} }