Merge "Moving prediction icons back into recycler view." into ub-launcher3-burnaby
This commit is contained in:
@@ -35,16 +35,4 @@
|
||||
android:focusable="true"
|
||||
android:descendantFocusability="afterDescendants" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/prediction_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/all_apps_prediction_bar_top_padding"
|
||||
android:paddingBottom="@dimen/all_apps_prediction_bar_bottom_padding"
|
||||
android:orientation="horizontal"
|
||||
android:focusable="true"
|
||||
android:descendantFocusability="afterDescendants"
|
||||
android:visibility="invisible" >
|
||||
</LinearLayout>
|
||||
|
||||
</com.android.launcher3.allapps.AllAppsRecyclerViewContainerView>
|
||||
@@ -18,10 +18,11 @@
|
||||
xmlns:launcher="http://schemas.android.com/apk/res-auto"
|
||||
style="@style/Icon.AllApps"
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="0dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_weight="1"
|
||||
android:paddingTop="@dimen/all_apps_prediction_icon_top_padding"
|
||||
android:paddingBottom="@dimen/all_apps_prediction_icon_bottom_padding"
|
||||
android:focusable="true"
|
||||
android:background="@drawable/focusable_view_bg"
|
||||
launcher:iconDisplay="all_apps" />
|
||||
|
||||
@@ -70,9 +70,9 @@
|
||||
<dimen name="all_apps_search_bar_prediction_bar_padding">8dp</dimen>
|
||||
<dimen name="all_apps_icon_top_bottom_padding">8dp</dimen>
|
||||
<dimen name="all_apps_icon_width_gap">24dp</dimen>
|
||||
<!-- The top padding should account for the general all_apps_list_top_bottom_padding -->
|
||||
<dimen name="all_apps_prediction_bar_top_padding">0dp</dimen>
|
||||
<dimen name="all_apps_prediction_bar_bottom_padding">16dp</dimen>
|
||||
<!-- The top padding should account for the existing all_apps_list_top_bottom_padding -->
|
||||
<dimen name="all_apps_prediction_icon_top_padding">8dp</dimen>
|
||||
<dimen name="all_apps_prediction_icon_bottom_padding">18dp</dimen>
|
||||
<dimen name="all_apps_list_top_bottom_padding">8dp</dimen>
|
||||
|
||||
<!-- Widget tray -->
|
||||
|
||||
@@ -75,7 +75,11 @@ final class FullMergeAlgorithm implements AlphabeticalAppsList.MergeAlgorithm {
|
||||
public boolean continueMerging(AlphabeticalAppsList.SectionInfo section,
|
||||
AlphabeticalAppsList.SectionInfo withSection,
|
||||
int sectionAppCount, int numAppsPerRow, int mergeCount) {
|
||||
// Merge EVERYTHING
|
||||
// Don't merge the predicted apps
|
||||
if (section.firstAppItem.viewType != AllAppsGridAdapter.ICON_VIEW_TYPE) {
|
||||
return false;
|
||||
}
|
||||
// Otherwise, merge every other section
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -103,6 +107,11 @@ final class SimpleSectionMergeAlgorithm implements AlphabeticalAppsList.MergeAlg
|
||||
public boolean continueMerging(AlphabeticalAppsList.SectionInfo section,
|
||||
AlphabeticalAppsList.SectionInfo withSection,
|
||||
int sectionAppCount, int numAppsPerRow, int mergeCount) {
|
||||
// Don't merge the predicted apps
|
||||
if (section.firstAppItem.viewType != AllAppsGridAdapter.ICON_VIEW_TYPE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Continue merging if the number of hanging apps on the final row is less than some
|
||||
// fixed number (ragged), the merged rows has yet to exceed some minimum row count,
|
||||
// and while the number of merged sections is less than some fixed number of merges
|
||||
@@ -127,17 +136,14 @@ final class SimpleSectionMergeAlgorithm implements AlphabeticalAppsList.MergeAlg
|
||||
* The all apps view container.
|
||||
*/
|
||||
public class AllAppsContainerView extends BaseContainerView implements DragSource,
|
||||
LauncherTransitionable, AlphabeticalAppsList.AdapterChangedCallback,
|
||||
AllAppsGridAdapter.PredictionBarSpacerCallbacks, View.OnTouchListener,
|
||||
View.OnLongClickListener, ViewTreeObserver.OnPreDrawListener,
|
||||
AllAppsSearchBarController.Callbacks, Stats.LaunchSourceProvider {
|
||||
LauncherTransitionable, View.OnTouchListener, View.OnLongClickListener,
|
||||
AllAppsSearchBarController.Callbacks {
|
||||
|
||||
private static final int MIN_ROWS_IN_MERGED_SECTION_PHONE = 3;
|
||||
private static final int MAX_NUM_MERGES_PHONE = 2;
|
||||
|
||||
@Thunk Launcher mLauncher;
|
||||
@Thunk AlphabeticalAppsList mApps;
|
||||
private LayoutInflater mLayoutInflater;
|
||||
private AllAppsGridAdapter mAdapter;
|
||||
private RecyclerView.LayoutManager mLayoutManager;
|
||||
private RecyclerView.ItemDecoration mItemDecoration;
|
||||
@@ -146,7 +152,6 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
||||
@Thunk View mContainerView;
|
||||
@Thunk View mRevealView;
|
||||
@Thunk AllAppsRecyclerView mAppsRecyclerView;
|
||||
@Thunk ViewGroup mPredictionBarView;
|
||||
@Thunk AllAppsSearchBarController mSearchBarController;
|
||||
private ViewGroup mSearchBarContainerView;
|
||||
private View mSearchBarView;
|
||||
@@ -159,18 +164,9 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
||||
private final Point mBoundsCheckLastTouchDownPos = new Point(-1, -1);
|
||||
// This coordinate is relative to its parent
|
||||
private final Point mIconLastTouchPos = new Point();
|
||||
// This coordinate is used to proxy click and long-click events to the prediction bar icons
|
||||
private final Point mPredictionIconTouchDownPos = new Point();
|
||||
// Normal container insets
|
||||
private int mPredictionBarHeight;
|
||||
private int mLastRecyclerViewScrollPos = -1;
|
||||
@Thunk boolean mFocusPredictionBarOnFirstBind;
|
||||
|
||||
private SpannableStringBuilder mSearchQueryBuilder = null;
|
||||
|
||||
private CheckLongPressHelper mPredictionIconCheckForLongPress;
|
||||
private View mPredictionIconUnderTouch;
|
||||
|
||||
public AllAppsContainerView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@@ -184,19 +180,10 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
||||
Resources res = context.getResources();
|
||||
|
||||
mLauncher = (Launcher) context;
|
||||
mLayoutInflater = LayoutInflater.from(context);
|
||||
DeviceProfile grid = mLauncher.getDeviceProfile();
|
||||
mPredictionBarHeight = (int) (grid.allAppsIconSizePx + grid.iconDrawablePaddingOriginalPx +
|
||||
Utilities.calculateTextHeight(grid.allAppsIconTextSizePx) +
|
||||
2 * res.getDimensionPixelSize(R.dimen.all_apps_icon_top_bottom_padding) +
|
||||
res.getDimensionPixelSize(R.dimen.all_apps_prediction_bar_top_padding) +
|
||||
res.getDimensionPixelSize(R.dimen.all_apps_prediction_bar_bottom_padding));
|
||||
mSectionNamesMargin = res.getDimensionPixelSize(R.dimen.all_apps_grid_view_start_margin);
|
||||
mApps = new AlphabeticalAppsList(context);
|
||||
mApps.setAdapterChangedCallback(this);
|
||||
mAdapter = new AllAppsGridAdapter(context, mApps, this, this, mLauncher, this);
|
||||
mAdapter = new AllAppsGridAdapter(context, mApps, this, mLauncher, this);
|
||||
mAdapter.setEmptySearchText(res.getString(R.string.all_apps_loading_message));
|
||||
mAdapter.setPredictionRowHeight(mPredictionBarHeight);
|
||||
mApps.setAdapter(mAdapter);
|
||||
mLayoutManager = mAdapter.getLayoutManager();
|
||||
mItemDecoration = mAdapter.getItemDecoration();
|
||||
@@ -310,17 +297,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
if (hasFocus) {
|
||||
if (!mApps.getPredictedApps().isEmpty()) {
|
||||
// If the prediction bar is going to be bound, then defer focusing until
|
||||
// it is first bound
|
||||
if (mPredictionBarView.getChildCount() == 0) {
|
||||
mFocusPredictionBarOnFirstBind = true;
|
||||
} else {
|
||||
mPredictionBarView.requestFocus();
|
||||
}
|
||||
} else {
|
||||
mAppsRecyclerView.requestFocus();
|
||||
}
|
||||
mAppsRecyclerView.requestFocus();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -333,7 +310,6 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
||||
// Load the all apps recycler view
|
||||
mAppsRecyclerView = (AllAppsRecyclerView) findViewById(R.id.apps_list_view);
|
||||
mAppsRecyclerView.setApps(mApps);
|
||||
mAppsRecyclerView.setPredictionBarHeight(mPredictionBarHeight);
|
||||
mAppsRecyclerView.setLayoutManager(mLayoutManager);
|
||||
mAppsRecyclerView.setAdapter(mAdapter);
|
||||
mAppsRecyclerView.setHasFixedSize(true);
|
||||
@@ -341,11 +317,6 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
||||
mAppsRecyclerView.addItemDecoration(mItemDecoration);
|
||||
}
|
||||
|
||||
// Fix the prediction bar height
|
||||
mPredictionBarView = (ViewGroup) findViewById(R.id.prediction_bar);
|
||||
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mPredictionBarView.getLayoutParams();
|
||||
lp.height = mPredictionBarHeight;
|
||||
|
||||
updateBackgroundAndPaddings();
|
||||
}
|
||||
|
||||
@@ -354,49 +325,6 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
||||
mLauncher.updateOverlayBounds(newBounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindPredictionBar() {
|
||||
updatePredictionBarVisibility();
|
||||
|
||||
List<AppInfo> predictedApps = mApps.getPredictedApps();
|
||||
|
||||
// Remove extra prediction icons
|
||||
while (mPredictionBarView.getChildCount() > mNumPredictedAppsPerRow) {
|
||||
mPredictionBarView.removeViewAt(mPredictionBarView.getChildCount() - 1);
|
||||
}
|
||||
|
||||
int childCount = mPredictionBarView.getChildCount();
|
||||
for (int i = 0; i < mNumPredictedAppsPerRow; i++) {
|
||||
BubbleTextView icon;
|
||||
if (i < childCount) {
|
||||
// If a child at that index exists, then get that child
|
||||
icon = (BubbleTextView) mPredictionBarView.getChildAt(i);
|
||||
} else {
|
||||
// Otherwise, inflate a new icon
|
||||
icon = (BubbleTextView) mLayoutInflater.inflate(
|
||||
R.layout.all_apps_prediction_bar_icon, mPredictionBarView, false);
|
||||
icon.setFocusable(true);
|
||||
icon.setLongPressTimeout(ViewConfiguration.get(getContext()).getLongPressTimeout());
|
||||
mPredictionBarView.addView(icon);
|
||||
}
|
||||
|
||||
// Either apply the app info to the child, or hide the view
|
||||
if (i < predictedApps.size()) {
|
||||
if (icon.getVisibility() != View.VISIBLE) {
|
||||
icon.setVisibility(View.VISIBLE);
|
||||
}
|
||||
icon.applyFromApplicationInfo(predictedApps.get(i));
|
||||
} else {
|
||||
icon.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
if (mFocusPredictionBarOnFirstBind) {
|
||||
mFocusPredictionBarOnFirstBind = false;
|
||||
mPredictionBarView.requestFocus();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
// Update the number of items in the grid before we measure the view
|
||||
@@ -476,22 +404,6 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
||||
lp.rightMargin = (getMeasuredWidth() - searchBarBounds.right) - backgroundPadding.right;
|
||||
mSearchBarContainerView.requestLayout();
|
||||
}
|
||||
|
||||
// Update the prediction bar insets as well
|
||||
mPredictionBarView = (ViewGroup) findViewById(R.id.prediction_bar);
|
||||
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mPredictionBarView.getLayoutParams();
|
||||
lp.leftMargin = padding.left + mAppsRecyclerView.getMaxScrollbarWidth();
|
||||
lp.rightMargin = padding.right + mAppsRecyclerView.getMaxScrollbarWidth();
|
||||
mPredictionBarView.requestLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreDraw() {
|
||||
if (mNumAppsPerRow > 0) {
|
||||
// Update the position of the prediction bar to match the scroll of the all apps list
|
||||
synchronizeToRecyclerViewScrollPosition(mAppsRecyclerView.getScrollPosition());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -620,18 +532,9 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAdapterItemsChanged() {
|
||||
updatePredictionBarVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace) {
|
||||
// Register for a pre-draw listener to synchronize the recycler view scroll to other views
|
||||
// in this container
|
||||
if (!toWorkspace) {
|
||||
getViewTreeObserver().addOnPreDrawListener(this);
|
||||
}
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -647,37 +550,11 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
||||
@Override
|
||||
public void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace) {
|
||||
if (toWorkspace) {
|
||||
getViewTreeObserver().removeOnPreDrawListener(this);
|
||||
mLastRecyclerViewScrollPos = -1;
|
||||
|
||||
// Reset the search bar after transitioning home
|
||||
mSearchBarController.reset();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the container when the recycler view is scrolled.
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
private void synchronizeToRecyclerViewScrollPosition(int scrollY) {
|
||||
if (mLastRecyclerViewScrollPos != scrollY) {
|
||||
mLastRecyclerViewScrollPos = scrollY;
|
||||
|
||||
// Scroll the prediction bar with the contents of the recycler view
|
||||
mPredictionBarView.setTranslationY(-scrollY + mAppsRecyclerView.getPaddingTop());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
|
||||
// If we were waiting for long-click, cancel the request once a child has started handling
|
||||
// the scrolling
|
||||
if (mPredictionIconCheckForLongPress != null) {
|
||||
mPredictionIconCheckForLongPress.cancelLongPress();
|
||||
}
|
||||
super.requestDisallowInterceptTouchEvent(disallowIntercept);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the touch events to dismiss all apps when clicking outside the bounds of the
|
||||
* recycler view.
|
||||
@@ -689,19 +566,6 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
||||
|
||||
switch (ev.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
// We workaround the fact that the recycler view needs the touches for the scroll
|
||||
// and we want to intercept it for clicks in the prediction bar by handling clicks
|
||||
// and long clicks in the prediction bar ourselves.
|
||||
if (mPredictionBarView != null && mPredictionBarView.getVisibility() == View.VISIBLE) {
|
||||
mPredictionIconTouchDownPos.set(x, y);
|
||||
mPredictionIconUnderTouch = findPredictedAppAtCoordinate(x, y);
|
||||
if (mPredictionIconUnderTouch != null) {
|
||||
mPredictionIconCheckForLongPress =
|
||||
new CheckLongPressHelper(mPredictionIconUnderTouch, this);
|
||||
mPredictionIconCheckForLongPress.postCheckForLongPress();
|
||||
}
|
||||
}
|
||||
|
||||
if (!mContentBounds.isEmpty()) {
|
||||
// Outset the fixed bounds and check if the touch is outside all apps
|
||||
Rect tmpRect = new Rect(mContentBounds);
|
||||
@@ -719,19 +583,6 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (mPredictionIconUnderTouch != null) {
|
||||
float dist = (float) Math.hypot(x - mPredictionIconTouchDownPos.x,
|
||||
y - mPredictionIconTouchDownPos.y);
|
||||
if (dist > ViewConfiguration.get(getContext()).getScaledTouchSlop()) {
|
||||
if (mPredictionIconCheckForLongPress != null) {
|
||||
mPredictionIconCheckForLongPress.cancelLongPress();
|
||||
}
|
||||
mPredictionIconCheckForLongPress = null;
|
||||
mPredictionIconUnderTouch = null;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
if (mBoundsCheckLastTouchDownPos.x > -1) {
|
||||
ViewConfiguration viewConfig = ViewConfiguration.get(getContext());
|
||||
@@ -745,26 +596,9 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger the click on the prediction bar icon if that's where we touched
|
||||
if (mPredictionIconUnderTouch != null &&
|
||||
!mPredictionIconCheckForLongPress.hasPerformedLongPress()) {
|
||||
mLauncher.onClick(mPredictionIconUnderTouch);
|
||||
}
|
||||
|
||||
// Fall through
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
mBoundsCheckLastTouchDownPos.set(-1, -1);
|
||||
mPredictionIconTouchDownPos.set(-1, -1);
|
||||
|
||||
// On touch up/cancel, cancel the long press on the prediction bar icon if it has
|
||||
// not yet been performed
|
||||
if (mPredictionIconCheckForLongPress != null) {
|
||||
mPredictionIconCheckForLongPress.cancelLongPress();
|
||||
mPredictionIconCheckForLongPress = null;
|
||||
}
|
||||
mPredictionIconUnderTouch = null;
|
||||
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
@@ -792,59 +626,4 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc
|
||||
mSearchQueryBuilder.clearSpans();
|
||||
Selection.setSelection(mSearchQueryBuilder, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillInLaunchSourceData(Bundle sourceData) {
|
||||
// Since the other cases are caught by the AllAppsRecyclerView LaunchSourceProvider, we just
|
||||
// handle the prediction bar icons here
|
||||
sourceData.putString(Stats.SOURCE_EXTRA_CONTAINER, Stats.CONTAINER_ALL_APPS);
|
||||
sourceData.putString(Stats.SOURCE_EXTRA_SUB_CONTAINER,
|
||||
Stats.SUB_CONTAINER_ALL_APPS_PREDICTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the predicted app in the prediction bar given a set of local coordinates.
|
||||
*/
|
||||
private View findPredictedAppAtCoordinate(int x, int y) {
|
||||
Rect hitRect = new Rect();
|
||||
|
||||
// Ensure that are touching in the recycler view
|
||||
int[] coord = {x, y};
|
||||
Utilities.mapCoordInSelfToDescendent(mAppsRecyclerView, this, coord);
|
||||
mAppsRecyclerView.getHitRect(hitRect);
|
||||
if (!hitRect.contains(coord[0], coord[1])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check against the children of the prediction bar
|
||||
coord[0] = x;
|
||||
coord[1] = y;
|
||||
Utilities.mapCoordInSelfToDescendent(mPredictionBarView, this, coord);
|
||||
for (int i = 0; i < mPredictionBarView.getChildCount(); i++) {
|
||||
View child = mPredictionBarView.getChildAt(i);
|
||||
if (child.getVisibility() != View.VISIBLE) {
|
||||
continue;
|
||||
}
|
||||
child.getHitRect(hitRect);
|
||||
if (hitRect.contains(coord[0], coord[1])) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the visibility of the prediction bar.
|
||||
* @return whether the prediction bar is visible
|
||||
*/
|
||||
private boolean updatePredictionBarVisibility() {
|
||||
boolean showPredictionBar = !mApps.getPredictedApps().isEmpty() &&
|
||||
(!mApps.hasFilter() || mSearchBarController.shouldShowPredictionBar());
|
||||
if (showPredictionBar) {
|
||||
mPredictionBarView.setVisibility(View.VISIBLE);
|
||||
} else if (!showPredictionBar) {
|
||||
mPredictionBarView.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
return showPredictionBar;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import com.android.launcher3.AppInfo;
|
||||
import com.android.launcher3.BubbleTextView;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.util.Thunk;
|
||||
@@ -52,17 +51,10 @@ class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.ViewHol
|
||||
public static final int SECTION_BREAK_VIEW_TYPE = 0;
|
||||
// A normal icon
|
||||
public static final int ICON_VIEW_TYPE = 1;
|
||||
// A prediction icon
|
||||
public static final int PREDICTION_ICON_VIEW_TYPE = 2;
|
||||
// The message shown when there are no filtered results
|
||||
public static final int EMPTY_SEARCH_VIEW_TYPE = 2;
|
||||
// The spacer used for the prediction bar
|
||||
public static final int PREDICTION_BAR_SPACER_TYPE = 3;
|
||||
|
||||
/**
|
||||
* Callback for when the prediction bar spacer is bound.
|
||||
*/
|
||||
public interface PredictionBarSpacerCallbacks {
|
||||
void onBindPredictionBar();
|
||||
}
|
||||
public static final int EMPTY_SEARCH_VIEW_TYPE = 3;
|
||||
|
||||
/**
|
||||
* ViewHolder for each icon.
|
||||
@@ -93,11 +85,13 @@ class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.ViewHol
|
||||
return mAppsPerRow;
|
||||
}
|
||||
|
||||
if (mApps.getAdapterItems().get(position).viewType != AllAppsGridAdapter.ICON_VIEW_TYPE) {
|
||||
// Both the section breaks and predictive bar span the full width
|
||||
return mAppsPerRow;
|
||||
} else {
|
||||
return 1;
|
||||
switch (mApps.getAdapterItems().get(position).viewType) {
|
||||
case AllAppsGridAdapter.ICON_VIEW_TYPE:
|
||||
case AllAppsGridAdapter.PREDICTION_ICON_VIEW_TYPE:
|
||||
return 1;
|
||||
default:
|
||||
// Section breaks span the full width
|
||||
return mAppsPerRow;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -141,7 +135,7 @@ class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.ViewHol
|
||||
|
||||
if (shouldDrawItemDivider(holder, items) && !hasDrawnPredictedAppsDivider) {
|
||||
// Draw the divider under the predicted apps
|
||||
int top = child.getTop() + child.getHeight() - mPredictionBarBottomPadding / 2;
|
||||
int top = child.getTop() + child.getHeight() + mPredictionBarDividerOffset;
|
||||
c.drawLine(mBackgroundPadding.left, top,
|
||||
parent.getWidth() - mBackgroundPadding.right, top,
|
||||
mPredictedAppsDividerPaint);
|
||||
@@ -264,7 +258,7 @@ class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.ViewHol
|
||||
private boolean shouldDrawItemDivider(ViewHolder holder,
|
||||
List<AlphabeticalAppsList.AdapterItem> items) {
|
||||
int pos = holder.getPosition();
|
||||
return items.get(pos).viewType == AllAppsGridAdapter.PREDICTION_BAR_SPACER_TYPE;
|
||||
return items.get(pos).viewType == AllAppsGridAdapter.PREDICTION_ICON_VIEW_TYPE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -285,19 +279,16 @@ class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.ViewHol
|
||||
}
|
||||
}
|
||||
|
||||
private Handler mHandler;
|
||||
private LayoutInflater mLayoutInflater;
|
||||
@Thunk AlphabeticalAppsList mApps;
|
||||
private GridLayoutManager mGridLayoutMgr;
|
||||
private GridSpanSizer mGridSizer;
|
||||
private GridItemDecoration mItemDecoration;
|
||||
@Thunk PredictionBarSpacerCallbacks mPredictionBarCb;
|
||||
private View.OnTouchListener mTouchListener;
|
||||
private View.OnClickListener mIconClickListener;
|
||||
private View.OnLongClickListener mIconLongClickListener;
|
||||
@Thunk final Rect mBackgroundPadding = new Rect();
|
||||
@Thunk int mPredictionBarHeight;
|
||||
@Thunk int mPredictionBarBottomPadding;
|
||||
@Thunk int mPredictionBarDividerOffset;
|
||||
@Thunk int mAppsPerRow;
|
||||
@Thunk boolean mIsRtl;
|
||||
private String mEmptySearchText;
|
||||
@@ -309,12 +300,10 @@ class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.ViewHol
|
||||
@Thunk Paint mPredictedAppsDividerPaint;
|
||||
|
||||
public AllAppsGridAdapter(Context context, AlphabeticalAppsList apps,
|
||||
PredictionBarSpacerCallbacks pbCb, View.OnTouchListener touchListener,
|
||||
View.OnClickListener iconClickListener, View.OnLongClickListener iconLongClickListener) {
|
||||
View.OnTouchListener touchListener, View.OnClickListener iconClickListener,
|
||||
View.OnLongClickListener iconLongClickListener) {
|
||||
Resources res = context.getResources();
|
||||
mHandler = new Handler();
|
||||
mApps = apps;
|
||||
mPredictionBarCb = pbCb;
|
||||
mGridSizer = new GridSpanSizer();
|
||||
mGridLayoutMgr = new GridLayoutManager(context, 1, GridLayoutManager.VERTICAL, false);
|
||||
mGridLayoutMgr.setSpanSizeLookup(mGridSizer);
|
||||
@@ -336,8 +325,9 @@ class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.ViewHol
|
||||
mPredictedAppsDividerPaint.setStrokeWidth(Utilities.pxFromDp(1f, res.getDisplayMetrics()));
|
||||
mPredictedAppsDividerPaint.setColor(0x1E000000);
|
||||
mPredictedAppsDividerPaint.setAntiAlias(true);
|
||||
mPredictionBarBottomPadding =
|
||||
res.getDimensionPixelSize(R.dimen.all_apps_prediction_bar_bottom_padding);
|
||||
mPredictionBarDividerOffset =
|
||||
(-res.getDimensionPixelSize(R.dimen.all_apps_prediction_icon_bottom_padding) +
|
||||
res.getDimensionPixelSize(R.dimen.all_apps_icon_top_bottom_padding)) / 2;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -348,13 +338,6 @@ class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.ViewHol
|
||||
mGridLayoutMgr.setSpanCount(appsPerRow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the prediction row height.
|
||||
*/
|
||||
public void setPredictionRowHeight(int height) {
|
||||
mPredictionBarHeight = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether we are in RTL mode.
|
||||
*/
|
||||
@@ -400,14 +383,7 @@ class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.ViewHol
|
||||
false));
|
||||
case SECTION_BREAK_VIEW_TYPE:
|
||||
return new ViewHolder(new View(parent.getContext()));
|
||||
case PREDICTION_BAR_SPACER_TYPE:
|
||||
// Create a view of a specific height to match the floating prediction bar
|
||||
View v = new View(parent.getContext());
|
||||
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT, mPredictionBarHeight);
|
||||
v.setLayoutParams(lp);
|
||||
return new ViewHolder(v);
|
||||
case ICON_VIEW_TYPE:
|
||||
case ICON_VIEW_TYPE: {
|
||||
BubbleTextView icon = (BubbleTextView) mLayoutInflater.inflate(
|
||||
R.layout.all_apps_icon, parent, false);
|
||||
icon.setOnTouchListener(mTouchListener);
|
||||
@@ -417,6 +393,18 @@ class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.ViewHol
|
||||
.getLongPressTimeout());
|
||||
icon.setFocusable(true);
|
||||
return new ViewHolder(icon);
|
||||
}
|
||||
case PREDICTION_ICON_VIEW_TYPE: {
|
||||
BubbleTextView icon = (BubbleTextView) mLayoutInflater.inflate(
|
||||
R.layout.all_apps_prediction_bar_icon, parent, false);
|
||||
icon.setOnTouchListener(mTouchListener);
|
||||
icon.setOnClickListener(mIconClickListener);
|
||||
icon.setOnLongClickListener(mIconLongClickListener);
|
||||
icon.setLongPressTimeout(ViewConfiguration.get(parent.getContext())
|
||||
.getLongPressTimeout());
|
||||
icon.setFocusable(true);
|
||||
return new ViewHolder(icon);
|
||||
}
|
||||
default:
|
||||
throw new RuntimeException("Unexpected view type");
|
||||
}
|
||||
@@ -425,21 +413,18 @@ class AllAppsGridAdapter extends RecyclerView.Adapter<AllAppsGridAdapter.ViewHol
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
switch (holder.getItemViewType()) {
|
||||
case ICON_VIEW_TYPE:
|
||||
case ICON_VIEW_TYPE: {
|
||||
AppInfo info = mApps.getAdapterItems().get(position).appInfo;
|
||||
BubbleTextView icon = (BubbleTextView) holder.mContent;
|
||||
icon.applyFromApplicationInfo(info);
|
||||
break;
|
||||
case PREDICTION_BAR_SPACER_TYPE:
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mPredictionBarCb != null) {
|
||||
mPredictionBarCb.onBindPredictionBar();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
case PREDICTION_ICON_VIEW_TYPE: {
|
||||
AppInfo info = mApps.getAdapterItems().get(position).appInfo;
|
||||
BubbleTextView icon = (BubbleTextView) holder.mContent;
|
||||
icon.applyFromApplicationInfo(info);
|
||||
break;
|
||||
}
|
||||
case EMPTY_SEARCH_VIEW_TYPE:
|
||||
TextView emptyViewText = (TextView) holder.mContent.findViewById(R.id.empty_text);
|
||||
emptyViewText.setText(mEmptySearchText);
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.android.launcher3.BaseRecyclerView;
|
||||
import com.android.launcher3.BaseRecyclerViewFastScrollBar;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Stats;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.util.Thunk;
|
||||
|
||||
import java.util.List;
|
||||
@@ -45,7 +46,6 @@ public class AllAppsRecyclerView extends BaseRecyclerView
|
||||
|
||||
private AlphabeticalAppsList mApps;
|
||||
private int mNumAppsPerRow;
|
||||
private int mPredictionBarHeight;
|
||||
|
||||
@Thunk BaseRecyclerViewFastScrollBar.FastScrollFocusableView mLastFastScrollFocusedView;
|
||||
@Thunk int mPrevFastScrollFocusedPosition;
|
||||
@@ -89,19 +89,12 @@ public class AllAppsRecyclerView extends BaseRecyclerView
|
||||
|
||||
RecyclerView.RecycledViewPool pool = getRecycledViewPool();
|
||||
int approxRows = (int) Math.ceil(grid.availableHeightPx / grid.allAppsIconSizePx);
|
||||
pool.setMaxRecycledViews(AllAppsGridAdapter.PREDICTION_BAR_SPACER_TYPE, 1);
|
||||
pool.setMaxRecycledViews(AllAppsGridAdapter.EMPTY_SEARCH_VIEW_TYPE, 1);
|
||||
pool.setMaxRecycledViews(AllAppsGridAdapter.ICON_VIEW_TYPE, approxRows * mNumAppsPerRow);
|
||||
pool.setMaxRecycledViews(AllAppsGridAdapter.PREDICTION_ICON_VIEW_TYPE, mNumAppsPerRow);
|
||||
pool.setMaxRecycledViews(AllAppsGridAdapter.SECTION_BREAK_VIEW_TYPE, approxRows);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the prediction bar height.
|
||||
*/
|
||||
public void setPredictionBarHeight(int height) {
|
||||
mPredictionBarHeight = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scrolls this recycler view to the top.
|
||||
*/
|
||||
@@ -109,21 +102,6 @@ public class AllAppsRecyclerView extends BaseRecyclerView
|
||||
scrollToPosition(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current scroll position.
|
||||
*/
|
||||
public int getScrollPosition() {
|
||||
List<AlphabeticalAppsList.AdapterItem> items = mApps.getAdapterItems();
|
||||
getCurScrollState(mScrollPosState, items);
|
||||
if (mScrollPosState.rowIndex != -1) {
|
||||
int predictionBarHeight = mApps.getPredictedApps().isEmpty() ? 0 : mPredictionBarHeight;
|
||||
return getPaddingTop() + predictionBarHeight +
|
||||
(mScrollPosState.rowIndex * mScrollPosState.rowHeight) -
|
||||
mScrollPosState.rowTopOffset;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to override the draw to ensure that we don't draw the overscroll effect beyond the
|
||||
* background bounds.
|
||||
@@ -189,9 +167,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView
|
||||
|
||||
// Map the touch position back to the scroll of the recycler view
|
||||
getCurScrollState(mScrollPosState, mApps.getAdapterItems());
|
||||
int predictionBarHeight = mApps.getPredictedApps().isEmpty() ? 0 : mPredictionBarHeight;
|
||||
int availableScrollHeight = getAvailableScrollHeight(rowCount, mScrollPosState.rowHeight,
|
||||
predictionBarHeight);
|
||||
int availableScrollHeight = getAvailableScrollHeight(rowCount, mScrollPosState.rowHeight, 0);
|
||||
LinearLayoutManager layoutManager = (LinearLayoutManager) getLayoutManager();
|
||||
if (mFastScrollMode == FAST_SCROLL_MODE_FREE_SCROLL) {
|
||||
layoutManager.scrollToPositionWithOffset(0, (int) -(availableScrollHeight * touchFraction));
|
||||
@@ -255,8 +231,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView
|
||||
return;
|
||||
}
|
||||
|
||||
int predictionBarHeight = mApps.getPredictedApps().isEmpty() ? 0 : mPredictionBarHeight;
|
||||
synchronizeScrollBarThumbOffsetToViewScroll(mScrollPosState, rowCount, predictionBarHeight);
|
||||
synchronizeScrollBarThumbOffsetToViewScroll(mScrollPosState, rowCount, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -293,8 +268,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView
|
||||
|
||||
// Calculate the full animation from the current scroll position to the final scroll
|
||||
// position, and then run the animation for the duration.
|
||||
int predictionBarHeight = mApps.getPredictedApps().isEmpty() ? 0 : mPredictionBarHeight;
|
||||
int curScrollY = getPaddingTop() + predictionBarHeight +
|
||||
int curScrollY = getPaddingTop() +
|
||||
(scrollPosState.rowIndex * scrollPosState.rowHeight) - scrollPosState.rowTopOffset;
|
||||
int newScrollY = getScrollAtPosition(position, scrollPosState.rowHeight);
|
||||
int numFrames = mFastScrollFrames.length;
|
||||
@@ -307,8 +281,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current scroll state of the apps rows, not including the prediction
|
||||
* bar.
|
||||
* Returns the current scroll state of the apps rows.
|
||||
*/
|
||||
private void getCurScrollState(ScrollPositionState stateOut,
|
||||
List<AlphabeticalAppsList.AdapterItem> items) {
|
||||
@@ -327,7 +300,8 @@ public class AllAppsRecyclerView extends BaseRecyclerView
|
||||
int position = getChildPosition(child);
|
||||
if (position != NO_POSITION) {
|
||||
AlphabeticalAppsList.AdapterItem item = items.get(position);
|
||||
if (item.viewType == AllAppsGridAdapter.ICON_VIEW_TYPE) {
|
||||
if (item.viewType == AllAppsGridAdapter.ICON_VIEW_TYPE ||
|
||||
item.viewType == AllAppsGridAdapter.PREDICTION_ICON_VIEW_TYPE) {
|
||||
stateOut.rowIndex = item.rowIndex;
|
||||
stateOut.rowTopOffset = getLayoutManager().getDecoratedTop(child);
|
||||
stateOut.rowHeight = child.getHeight();
|
||||
@@ -342,9 +316,10 @@ public class AllAppsRecyclerView extends BaseRecyclerView
|
||||
*/
|
||||
private int getScrollAtPosition(int position, int rowHeight) {
|
||||
AlphabeticalAppsList.AdapterItem item = mApps.getAdapterItems().get(position);
|
||||
if (item.viewType == AllAppsGridAdapter.ICON_VIEW_TYPE) {
|
||||
int predictionBarHeight = mApps.getPredictedApps().isEmpty() ? 0 : mPredictionBarHeight;
|
||||
return getPaddingTop() + predictionBarHeight + item.rowIndex * rowHeight;
|
||||
if (item.viewType == AllAppsGridAdapter.ICON_VIEW_TYPE ||
|
||||
item.viewType == AllAppsGridAdapter.PREDICTION_ICON_VIEW_TYPE) {
|
||||
int offset = item.rowIndex > 0 ? getPaddingTop() : 0;
|
||||
return offset + item.rowIndex * rowHeight;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ public class AllAppsRecyclerViewContainerView extends FrameLayout
|
||||
implements BubbleTextShadowHandler {
|
||||
|
||||
private final ClickShadowView mTouchFeedbackView;
|
||||
private View mPredictionBarView;
|
||||
|
||||
public AllAppsRecyclerViewContainerView(Context context) {
|
||||
this(context, null);
|
||||
@@ -60,13 +59,6 @@ public class AllAppsRecyclerViewContainerView extends FrameLayout
|
||||
addView(mTouchFeedbackView, size, size);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
|
||||
mPredictionBarView = findViewById(R.id.prediction_bar);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPressedIcon(BubbleTextView icon, Bitmap background) {
|
||||
if (icon == null || background == null) {
|
||||
@@ -77,33 +69,4 @@ public class AllAppsRecyclerViewContainerView extends FrameLayout
|
||||
mTouchFeedbackView.animateShadow();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This allows us to have custom drawing order, while keeping touch handling in correct z-order.
|
||||
*/
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
final long drawingTime = getDrawingTime();
|
||||
|
||||
// Draw the click feedback first (since it is always on the bottom)
|
||||
if (mTouchFeedbackView != null && mTouchFeedbackView.getVisibility() == View.VISIBLE) {
|
||||
drawChild(canvas, mTouchFeedbackView, drawingTime);
|
||||
}
|
||||
|
||||
// Then draw the prediction bar, since it needs to be "under" the recycler view to get the
|
||||
// right edge effect to be drawn over it
|
||||
if (mPredictionBarView != null && mPredictionBarView.getVisibility() == View.VISIBLE) {
|
||||
drawChild(canvas, mPredictionBarView, drawingTime);
|
||||
}
|
||||
|
||||
// Draw the remaining views
|
||||
int childCount = getChildCount();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
View v = getChildAt(i);
|
||||
if (v != mTouchFeedbackView && v != mPredictionBarView &&
|
||||
v.getVisibility() == View.VISIBLE) {
|
||||
drawChild(canvas, v, drawingTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ public abstract class AllAppsSearchBarController {
|
||||
* Returns whether the prediction bar should currently be visible depending on the state of
|
||||
* the search bar.
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract boolean shouldShowPredictionBar();
|
||||
|
||||
/**
|
||||
|
||||
@@ -110,10 +110,10 @@ public class AlphabeticalAppsList {
|
||||
return item;
|
||||
}
|
||||
|
||||
public static AdapterItem asPredictionBarSpacer(int pos) {
|
||||
AdapterItem item = new AdapterItem();
|
||||
item.viewType = AllAppsGridAdapter.PREDICTION_BAR_SPACER_TYPE;
|
||||
item.position = pos;
|
||||
public static AdapterItem asPredictedApp(int pos, SectionInfo section, String sectionName,
|
||||
int sectionAppIndex, AppInfo appInfo, int appIndex) {
|
||||
AdapterItem item = asApp(pos, section, sectionName, sectionAppIndex, appInfo, appIndex);
|
||||
item.viewType = AllAppsGridAdapter.PREDICTION_ICON_VIEW_TYPE;
|
||||
return item;
|
||||
}
|
||||
|
||||
@@ -131,13 +131,6 @@ public class AlphabeticalAppsList {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to notify when the set of adapter items have changed.
|
||||
*/
|
||||
public interface AdapterChangedCallback {
|
||||
void onAdapterItemsChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Common interface for different merging strategies.
|
||||
*/
|
||||
@@ -171,7 +164,6 @@ public class AlphabeticalAppsList {
|
||||
private AlphabeticIndexCompat mIndexer;
|
||||
private AppNameComparator mAppNameComparator;
|
||||
private MergeAlgorithm mMergeAlgorithm;
|
||||
private AdapterChangedCallback mAdapterChangedCallback;
|
||||
private int mNumAppsPerRow;
|
||||
private int mNumPredictedAppsPerRow;
|
||||
private int mNumAppRowsInAdapter;
|
||||
@@ -182,13 +174,6 @@ public class AlphabeticalAppsList {
|
||||
mAppNameComparator = new AppNameComparator(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the apps updated callback.
|
||||
*/
|
||||
public void setAdapterChangedCallback(AdapterChangedCallback cb) {
|
||||
mAdapterChangedCallback = cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the number of apps per row.
|
||||
*/
|
||||
@@ -284,13 +269,6 @@ public class AlphabeticalAppsList {
|
||||
onAppsUpdated();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current set of predicted apps.
|
||||
*/
|
||||
public List<AppInfo> getPredictedApps() {
|
||||
return mPredictedApps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current set of apps.
|
||||
*/
|
||||
@@ -426,13 +404,25 @@ public class AlphabeticalAppsList {
|
||||
}
|
||||
|
||||
if (!mPredictedApps.isEmpty()) {
|
||||
// Create a new spacer for the prediction bar
|
||||
AdapterItem sectionItem = AdapterItem.asPredictionBarSpacer(position++);
|
||||
mAdapterItems.add(sectionItem);
|
||||
// Add a fastscroller section for the prediction bar
|
||||
// Add a section for the predictions
|
||||
lastSectionInfo = new SectionInfo();
|
||||
lastFastScrollerSectionInfo = new FastScrollSectionInfo("");
|
||||
lastFastScrollerSectionInfo.fastScrollToItem = sectionItem;
|
||||
AdapterItem sectionItem = AdapterItem.asSectionBreak(position++, lastSectionInfo);
|
||||
mSections.add(lastSectionInfo);
|
||||
mFastScrollerSections.add(lastFastScrollerSectionInfo);
|
||||
mAdapterItems.add(sectionItem);
|
||||
|
||||
// Add the predicted app items
|
||||
for (AppInfo info : mPredictedApps) {
|
||||
AdapterItem appItem = AdapterItem.asPredictedApp(position++, lastSectionInfo,
|
||||
"", lastSectionInfo.numApps++, info, appIndex++);
|
||||
if (lastSectionInfo.firstAppItem == null) {
|
||||
lastSectionInfo.firstAppItem = appItem;
|
||||
lastFastScrollerSectionInfo.fastScrollToItem = appItem;
|
||||
}
|
||||
mAdapterItems.add(appItem);
|
||||
mFilteredApps.add(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,7 +470,8 @@ public class AlphabeticalAppsList {
|
||||
item.rowIndex = 0;
|
||||
if (item.viewType == AllAppsGridAdapter.SECTION_BREAK_VIEW_TYPE) {
|
||||
numAppsInSection = 0;
|
||||
} else if (item.viewType == AllAppsGridAdapter.ICON_VIEW_TYPE) {
|
||||
} else if (item.viewType == AllAppsGridAdapter.ICON_VIEW_TYPE ||
|
||||
item.viewType == AllAppsGridAdapter.PREDICTION_ICON_VIEW_TYPE) {
|
||||
if (numAppsInSection % mNumAppsPerRow == 0) {
|
||||
numAppsInRow = 0;
|
||||
rowIndex++;
|
||||
@@ -493,19 +484,18 @@ public class AlphabeticalAppsList {
|
||||
}
|
||||
mNumAppRowsInAdapter = rowIndex + 1;
|
||||
|
||||
// Pre-calculate all the fast scroller fractions based on the number of rows, if we have
|
||||
// predicted apps, then we should account for that as a row in the touchFraction
|
||||
float rowFraction = 1f / (mNumAppRowsInAdapter + (mPredictedApps.isEmpty() ? 0 : 1));
|
||||
float initialOffset = mPredictedApps.isEmpty() ? 0 : rowFraction;
|
||||
// Pre-calculate all the fast scroller fractions based on the number of rows
|
||||
float rowFraction = 1f / mNumAppRowsInAdapter;
|
||||
for (FastScrollSectionInfo info : mFastScrollerSections) {
|
||||
AdapterItem item = info.fastScrollToItem;
|
||||
if (item.viewType != AllAppsGridAdapter.ICON_VIEW_TYPE) {
|
||||
if (item.viewType != AllAppsGridAdapter.ICON_VIEW_TYPE &&
|
||||
item.viewType != AllAppsGridAdapter.PREDICTION_ICON_VIEW_TYPE) {
|
||||
info.touchFraction = 0f;
|
||||
continue;
|
||||
}
|
||||
|
||||
float subRowFraction = item.rowAppIndex * (rowFraction / mNumAppsPerRow);
|
||||
info.touchFraction = initialOffset + item.rowIndex * rowFraction + subRowFraction;
|
||||
info.touchFraction = item.rowIndex * rowFraction + subRowFraction;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -513,10 +503,6 @@ public class AlphabeticalAppsList {
|
||||
if (mAdapter != null) {
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
if (mAdapterChangedCallback != null) {
|
||||
mAdapterChangedCallback.onAdapterItemsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private List<AppInfo> getFiltersAppInfos() {
|
||||
|
||||
@@ -125,8 +125,7 @@ final class DefaultAppSearchController extends AllAppsSearchBarController
|
||||
|
||||
@Override
|
||||
public boolean shouldShowPredictionBar() {
|
||||
// Keep showing the prediction bar if the input query is empty
|
||||
return mSearchBarEditView.getEditableText().toString().isEmpty();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user