diff --git a/quickstep/res/layout/taskbar_all_apps.xml b/quickstep/res/layout/taskbar_all_apps.xml
index d402469833..34d4b231b1 100644
--- a/quickstep/res/layout/taskbar_all_apps.xml
+++ b/quickstep/res/layout/taskbar_all_apps.xml
@@ -33,6 +33,10 @@
layout="@layout/all_apps_bottom_sheet_background"
android:visibility="gone" />
+
+
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java
index 0ea2aa0647..51fa4d9f3a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java
@@ -44,9 +44,10 @@ public class TaskbarAllAppsContainerView extends
}
@Override
- protected BaseAllAppsAdapter getAdapter(AlphabeticalAppsList mAppsList,
+ protected BaseAllAppsAdapter createAdapter(
+ AlphabeticalAppsList appsList,
BaseAdapterProvider[] adapterProviders) {
- return new AllAppsGridAdapter<>(mActivityContext, getLayoutInflater(), mAppsList,
+ return new AllAppsGridAdapter<>(mActivityContext, getLayoutInflater(), appsList,
adapterProviders);
}
}
diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml
index 2ac7e63a15..d0d82d48bd 100644
--- a/res/layout/all_apps.xml
+++ b/res/layout/all_apps.xml
@@ -29,6 +29,10 @@
layout="@layout/all_apps_bottom_sheet_background"
android:visibility="gone" />
+
+
diff --git a/res/layout/search_results_rv_layout.xml b/res/layout/search_results_rv_layout.xml
new file mode 100644
index 0000000000..567cb5f4fc
--- /dev/null
+++ b/res/layout/search_results_rv_layout.xml
@@ -0,0 +1,24 @@
+
+
+
diff --git a/res/layout/secondary_launcher.xml b/res/layout/secondary_launcher.xml
index 0fe05ee721..635db141dd 100644
--- a/res/layout/secondary_launcher.xml
+++ b/res/layout/secondary_launcher.xml
@@ -59,6 +59,10 @@
layout="@layout/all_apps_bottom_sheet_background"
android:visibility="gone" />
+
+
diff --git a/src/com/android/launcher3/BaseRecyclerView.java b/src/com/android/launcher3/FastScrollRecyclerView.java
similarity index 94%
rename from src/com/android/launcher3/BaseRecyclerView.java
rename to src/com/android/launcher3/FastScrollRecyclerView.java
index b6d3fc5304..f117069144 100644
--- a/src/com/android/launcher3/BaseRecyclerView.java
+++ b/src/com/android/launcher3/FastScrollRecyclerView.java
@@ -23,6 +23,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo;
+import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.android.launcher3.compat.AccessibilityManagerCompat;
@@ -36,19 +37,19 @@ import com.android.launcher3.views.RecyclerViewFastScroller;
* Enable fast scroller.
*
*/
-public abstract class BaseRecyclerView extends RecyclerView {
+public abstract class FastScrollRecyclerView extends RecyclerView {
protected RecyclerViewFastScroller mScrollbar;
- public BaseRecyclerView(Context context) {
+ public FastScrollRecyclerView(Context context) {
this(context, null);
}
- public BaseRecyclerView(Context context, AttributeSet attrs) {
+ public FastScrollRecyclerView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
- public BaseRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {
+ public FastScrollRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@@ -65,6 +66,7 @@ public abstract class BaseRecyclerView extends RecyclerView {
onUpdateScrollbar(0);
}
+ @Nullable
public RecyclerViewFastScroller getScrollbar() {
return mScrollbar;
}
@@ -198,4 +200,4 @@ public abstract class BaseRecyclerView extends RecyclerView {
}
scrollToPosition(0);
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
index 47f2dd50aa..2368cf7ce1 100644
--- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
@@ -82,7 +82,7 @@ public class ActivityAllAppsContainerView mActivityContext.startActivitySafely(v,
marketSearchIntent, null);
for (int i = 0; i < mAH.size(); i++) {
- mAH.get(i).adapter.setLastSearchQuery(query, marketSearchClickListener);
+ mAH.get(i).mAdapter.setLastSearchQuery(query, marketSearchClickListener);
}
mIsSearching = true;
rebindAdapters();
@@ -101,7 +101,7 @@ public class ActivityAllAppsContainerView results) {
- if (getApps().setSearchResults(results)) {
+ if (getSearchResultList().setSearchResults(results)) {
for (int i = 0; i < mAH.size(); i++) {
if (mAH.get(i).mRecyclerView != null) {
mAH.get(i).mRecyclerView.onSearchResultsChanged();
@@ -148,7 +148,7 @@ public class ActivityAllAppsContainerView mHeaderThreshold) {
bgVisible = false;
@@ -248,7 +257,7 @@ public class ActivityAllAppsContainerView mAppsList,
+ protected BaseAllAppsAdapter createAdapter(AlphabeticalAppsList appsList,
BaseAdapterProvider[] adapterProviders) {
- return new AllAppsGridAdapter<>(mActivityContext, getLayoutInflater(), mAppsList,
+ return new AllAppsGridAdapter<>(mActivityContext, getLayoutInflater(), appsList,
adapterProviders);
}
}
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 88e7fc0514..af17cf72e9 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -35,8 +35,8 @@ import android.view.View;
import androidx.recyclerview.widget.RecyclerView;
-import com.android.launcher3.BaseRecyclerView;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.FastScrollRecyclerView;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
@@ -50,13 +50,13 @@ import java.util.List;
/**
* A RecyclerView with custom fast scroll support for the all apps view.
*/
-public class AllAppsRecyclerView extends BaseRecyclerView {
- private static final String TAG = "AllAppsContainerView";
+public class AllAppsRecyclerView extends FastScrollRecyclerView {
+ protected static final String TAG = "AllAppsRecyclerView";
private static final boolean DEBUG = false;
private static final boolean DEBUG_LATENCY = Utilities.isPropertyEnabled(SEARCH_LOGGING);
- private AlphabeticalAppsList> mApps;
- private final int mNumAppsPerRow;
+ protected AlphabeticalAppsList> mApps;
+ protected final int mNumAppsPerRow;
// The specific view heights that we use to calculate scroll
private final SparseIntArray mViewHeights = new SparseIntArray();
@@ -91,8 +91,8 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
};
// The empty-search result background
- private AllAppsBackgroundDrawable mEmptySearchBackground;
- private int mEmptySearchBackgroundTopOffset;
+ protected AllAppsBackgroundDrawable mEmptySearchBackground;
+ protected int mEmptySearchBackgroundTopOffset;
public AllAppsRecyclerView(Context context) {
this(context, null);
@@ -127,7 +127,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
return mApps;
}
- private void updatePoolSize() {
+ protected void updatePoolSize() {
DeviceProfile grid = ActivityContext.lookupContext(getContext()).getDeviceProfile();
RecyclerView.RecycledViewPool pool = getRecycledViewPool();
int approxRows = (int) Math.ceil(grid.availableHeightPx / grid.allAppsIconSizePx);
@@ -152,8 +152,8 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
Log.d(TAG, "onDraw at = " + System.currentTimeMillis());
}
if (DEBUG_LATENCY) {
- Log.d(SEARCH_LOGGING,
- "-- Recycle view onDraw, time stamp = " + System.currentTimeMillis());
+ Log.d(SEARCH_LOGGING, getClass().getSimpleName() + " onDraw; time stamp = "
+ + System.currentTimeMillis());
}
super.onDraw(c);
}
@@ -341,13 +341,6 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
}
}
- @Override
- public boolean supportsFastScrolling() {
- // Only allow fast scrolling when the user is not searching, since the results are not
- // grouped in a meaningful order
- return !mApps.hasFilter();
- }
-
@Override
public int getCurrentScrollY() {
// Return early if there are no items or we haven't been measured
@@ -358,7 +351,7 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
// Calculate the y and offset for the item
View child = getChildAt(0);
- int position = getChildPosition(child);
+ int position = getChildAdapterPosition(child);
if (position == NO_POSITION) {
return -1;
}
@@ -448,14 +441,4 @@ public class AllAppsRecyclerView extends BaseRecyclerView {
public boolean hasOverlappingRendering() {
return false;
}
-
- /**
- * Returns distance between left and right app icons
- */
- public int getTabWidth() {
- DeviceProfile grid = ActivityContext.lookupContext(getContext()).getDeviceProfile();
- int totalWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
- int iconPadding = totalWidth / grid.numShownAllAppsColumns - grid.allAppsIconSizePx;
- return totalWidth - iconPadding - grid.allAppsIconDrawablePaddingPx;
- }
}
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 3600bd26b1..a4a208533a 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -84,7 +84,7 @@ public class AllAppsTransitionController
@Override
public Float get(AllAppsTransitionController controller) {
if (controller.mIsTablet) {
- return controller.mAppsView.getRecyclerViewContainer().getTranslationY();
+ return controller.mAppsView.getActiveRecyclerView().getTranslationY();
} else {
return controller.getAppsViewPullbackTranslationY().get(
controller.mAppsView);
@@ -94,8 +94,7 @@ public class AllAppsTransitionController
@Override
public void setValue(AllAppsTransitionController controller, float translation) {
if (controller.mIsTablet) {
- controller.mAppsView.getRecyclerViewContainer().setTranslationY(
- translation);
+ controller.mAppsView.getActiveRecyclerView().setTranslationY(translation);
} else {
controller.getAppsViewPullbackTranslationY().set(controller.mAppsView,
translation);
@@ -109,7 +108,7 @@ public class AllAppsTransitionController
@Override
public Float get(AllAppsTransitionController controller) {
if (controller.mIsTablet) {
- return controller.mAppsView.getRecyclerViewContainer().getAlpha();
+ return controller.mAppsView.getActiveRecyclerView().getAlpha();
} else {
return controller.getAppsViewPullbackAlpha().getValue();
}
@@ -118,7 +117,7 @@ public class AllAppsTransitionController
@Override
public void setValue(AllAppsTransitionController controller, float alpha) {
if (controller.mIsTablet) {
- controller.mAppsView.getRecyclerViewContainer().setAlpha(alpha);
+ controller.mAppsView.getActiveRecyclerView().setAlpha(alpha);
} else {
controller.getAppsViewPullbackAlpha().setValue(alpha);
}
diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
index 4ccfd39c12..45a567dd19 100644
--- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
+++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
@@ -21,6 +21,7 @@ import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_SEARCH_
import android.content.Context;
+import androidx.annotation.Nullable;
import androidx.recyclerview.widget.DiffUtil;
import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem;
@@ -72,6 +73,7 @@ public class AlphabeticalAppsList implement
// The set of apps from the system
private final List mApps = new ArrayList<>();
+ @Nullable
private final AllAppsStore mAllAppsStore;
// The number of results in current adapter
@@ -89,14 +91,16 @@ public class AlphabeticalAppsList implement
private int mNumAppRowsInAdapter;
private Predicate mItemFilter;
- public AlphabeticalAppsList(Context context, AllAppsStore appsStore,
+ public AlphabeticalAppsList(Context context, @Nullable AllAppsStore appsStore,
WorkAdapterProvider adapterProvider) {
mAllAppsStore = appsStore;
mActivityContext = ActivityContext.lookupContext(context);
mAppNameComparator = new AppInfoComparator(context);
mWorkAdapterProvider = adapterProvider;
mNumAppsPerRowAllApps = mActivityContext.getDeviceProfile().inv.numAllAppsColumns;
- mAllAppsStore.addUpdateListener(this);
+ if (mAllAppsStore != null) {
+ mAllAppsStore.addUpdateListener(this);
+ }
}
public void updateItemFilter(Predicate itemFilter) {
@@ -162,9 +166,9 @@ public class AlphabeticalAppsList implement
}
/**
- * Returns whether there are is a filter set.
+ * Returns whether there are search results which will hide the A-Z list.
*/
- public boolean hasFilter() {
+ public boolean hasSearchResults() {
return !mSearchResults.isEmpty();
}
@@ -172,7 +176,7 @@ public class AlphabeticalAppsList implement
* Returns whether there are no filtered results.
*/
public boolean hasNoFilteredResults() {
- return hasFilter() && mAccessibilityResultsCount == 0;
+ return hasSearchResults() && mAccessibilityResultsCount == 0;
}
/**
@@ -195,11 +199,14 @@ public class AlphabeticalAppsList implement
*/
@Override
public void onAppsUpdated() {
+ if (mAllAppsStore == null) {
+ return;
+ }
// Sort the list of apps
mApps.clear();
Stream appSteam = Stream.of(mAllAppsStore.getApps());
- if (!hasFilter() && mItemFilter != null) {
+ if (!hasSearchResults() && mItemFilter != null) {
appSteam = appSteam.filter(mItemFilter);
}
appSteam = appSteam.sorted(mAppNameComparator);
@@ -240,7 +247,18 @@ public class AlphabeticalAppsList implement
// Recreate the filtered and sectioned apps (for convenience for the grid layout) from the
// ordered set of sections
- if (!hasFilter()) {
+ if (hasSearchResults()) {
+ mAdapterItems.addAll(mSearchResults);
+ if (!FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
+ // Append the search market item
+ if (hasNoFilteredResults()) {
+ mAdapterItems.add(new AdapterItem(VIEW_TYPE_EMPTY_SEARCH));
+ } else {
+ mAdapterItems.add(new AdapterItem(VIEW_TYPE_ALL_APPS_DIVIDER));
+ }
+ mAdapterItems.add(new AdapterItem(VIEW_TYPE_SEARCH_MARKET));
+ }
+ } else {
int position = 0;
if (mWorkAdapterProvider != null) {
position += mWorkAdapterProvider.addWorkItems(mAdapterItems);
@@ -260,17 +278,6 @@ public class AlphabeticalAppsList implement
}
position++;
}
- } else {
- mAdapterItems.addAll(mSearchResults);
- if (!FeatureFlags.ENABLE_DEVICE_SEARCH.get()) {
- // Append the search market item
- if (hasNoFilteredResults()) {
- mAdapterItems.add(new AdapterItem(VIEW_TYPE_EMPTY_SEARCH));
- } else {
- mAdapterItems.add(new AdapterItem(VIEW_TYPE_ALL_APPS_DIVIDER));
- }
- mAdapterItems.add(new AdapterItem(VIEW_TYPE_SEARCH_MARKET));
- }
}
mAccessibilityResultsCount = (int) mAdapterItems.stream()
.filter(AdapterItem::isCountedForAccessibility).count();
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
index fc527976ab..2c04fc7753 100644
--- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
@@ -63,6 +63,7 @@ import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.views.BaseDragLayer;
import com.android.launcher3.views.RecyclerViewFastScroller;
import com.android.launcher3.views.ScrimView;
import com.android.launcher3.views.SpringRelativeLayout;
@@ -83,7 +84,7 @@ public abstract class BaseAllAppsContainerView= 0
- && mActivityContext.getDragLayer().isEventOverView(rv.getScrollbar(), ev)) {
+ if (rv.getScrollbar() != null
+ && rv.getScrollbar().getThumbOffsetY() >= 0
+ && dragLayer.isEventOverView(rv.getScrollbar(), ev)) {
return false;
}
- return rv.shouldContainerScroll(ev, mActivityContext.getDragLayer());
+ return rv.shouldContainerScroll(ev, dragLayer);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
AllAppsRecyclerView rv = getActiveRecyclerView();
- if (rv != null && rv.getScrollbar().isHitInParent(ev.getX(), ev.getY(),
- mFastScrollerOffset)) {
+ if (rv != null && rv.getScrollbar() != null
+ && rv.getScrollbar().isHitInParent(ev.getX(), ev.getY(), mFastScrollerOffset)) {
mTouchHandler = rv.getScrollbar();
} else {
mTouchHandler = null;
@@ -284,8 +289,8 @@ public abstract class BaseAllAppsContainerView false);
rebindAdapters(true /* force */);
mBottomSheetBackground = findViewById(R.id.bottom_sheet_background);
@@ -388,7 +417,7 @@ public abstract class BaseAllAppsContainerView {
+ adapterHolder.mPadding.bottom = bottomPadding;
+ adapterHolder.mPadding.left =
+ adapterHolder.mPadding.right = grid.allAppsLeftRightPadding;
+ adapterHolder.applyPadding();
+ });
}
private void setDeviceManagementResources() {
@@ -502,18 +553,23 @@ public abstract class BaseAllAppsContainerView getApps() {
- return mAH.get(AdapterHolder.MAIN).mAppsList;
+ public AlphabeticalAppsList getSearchResultList() {
+ return mAH.get(AdapterHolder.SEARCH).mAppsList;
}
public FloatingHeaderView getFloatingHeaderView() {
@@ -579,35 +630,40 @@ public abstract class BaseAllAppsContainerView {
+ adapterHolder.mPadding.top = padding;
+ adapterHolder.applyPadding();
+ if (adapterHolder.mRecyclerView != null) {
+ adapterHolder.mRecyclerView.scrollToTop();
}
- }
+ });
}
public boolean isHeaderVisible() {
@@ -623,7 +679,7 @@ public abstract class BaseAllAppsContainerView mAppsList,
+ protected abstract BaseAllAppsAdapter createAdapter(AlphabeticalAppsList mAppsList,
BaseAdapterProvider[] adapterProviders);
protected int getHeaderBottom() {
return (int) getTranslationY();
}
- /** Holds a {@link BaseAllAppsAdapter} and related fields. */
- public class AdapterHolder {
- public static final int MAIN = 0;
- public static final int WORK = 1;
-
- private final boolean mIsWork;
- public final BaseAllAppsAdapter adapter;
- final RecyclerView.LayoutManager mLayoutManager;
- final AlphabeticalAppsList mAppsList;
- final Rect mPadding = new Rect();
- AllAppsRecyclerView mRecyclerView;
-
- AdapterHolder(boolean isWork) {
- mIsWork = isWork;
- mAppsList = new AlphabeticalAppsList<>(mActivityContext, mAllAppsStore,
- isWork ? mWorkManager.getAdapterProvider() : null);
-
- BaseAdapterProvider[] adapterProviders =
- isWork ? new BaseAdapterProvider[]{mMainAdapterProvider,
- mWorkManager.getAdapterProvider()}
- : new BaseAdapterProvider[]{mMainAdapterProvider};
-
- adapter = getAdapter(mAppsList, adapterProviders);
- mAppsList.setAdapter(adapter);
- mLayoutManager = adapter.getLayoutManager();
- }
-
- void setup(@NonNull View rv, @Nullable Predicate matcher) {
- mAppsList.updateItemFilter(matcher);
- mRecyclerView = (AllAppsRecyclerView) rv;
- mRecyclerView.setEdgeEffectFactory(createEdgeEffectFactory());
- mRecyclerView.setApps(mAppsList);
- mRecyclerView.setLayoutManager(mLayoutManager);
- mRecyclerView.setAdapter(adapter);
- mRecyclerView.setHasFixedSize(true);
- // No animations will occur when changes occur to the items in this RecyclerView.
- mRecyclerView.setItemAnimator(null);
- mRecyclerView.addOnScrollListener(mScrollListener);
- FocusedItemDecorator focusedItemDecorator = new FocusedItemDecorator(mRecyclerView);
- mRecyclerView.addItemDecoration(focusedItemDecorator);
- adapter.setIconFocusListener(focusedItemDecorator.getFocusListener());
- applyPadding();
- }
-
- void applyPadding() {
- if (mRecyclerView != null) {
- int bottomOffset = 0;
- if (mIsWork && mWorkManager.getWorkModeSwitch() != null) {
- bottomOffset = mInsets.bottom + mWorkManager.getWorkModeSwitch().getHeight();
- }
- mRecyclerView.setPadding(mPadding.left, mPadding.top, mPadding.right,
- mPadding.bottom + bottomOffset);
- }
- }
- }
-
/**
* Returns a view that denotes the visible part of all apps container view.
*/
public View getVisibleContainerView() {
return mActivityContext.getDeviceProfile().isTablet ? mBottomSheetBackground : this;
}
+
+ /** Holds a {@link BaseAllAppsAdapter} and related fields. */
+ public class AdapterHolder {
+ public static final int MAIN = 0;
+ public static final int WORK = 1;
+ public static final int SEARCH = 2;
+
+ private final int mType;
+ public final BaseAllAppsAdapter mAdapter;
+ final RecyclerView.LayoutManager mLayoutManager;
+ final AlphabeticalAppsList mAppsList;
+ final Rect mPadding = new Rect();
+ AllAppsRecyclerView mRecyclerView;
+
+ AdapterHolder(int type) {
+ mType = type;
+ mAppsList = new AlphabeticalAppsList<>(mActivityContext,
+ isSearch() ? null : mAllAppsStore,
+ isWork() ? mWorkManager.getAdapterProvider() : null);
+
+ BaseAdapterProvider[] adapterProviders =
+ isWork() ? new BaseAdapterProvider[]{mMainAdapterProvider,
+ mWorkManager.getAdapterProvider()}
+ : new BaseAdapterProvider[]{mMainAdapterProvider};
+
+ mAdapter = createAdapter(mAppsList, adapterProviders);
+ mAppsList.setAdapter(mAdapter);
+ mLayoutManager = mAdapter.getLayoutManager();
+ }
+
+ void setup(@NonNull View rv, @Nullable Predicate matcher) {
+ mAppsList.updateItemFilter(matcher);
+ mRecyclerView = (AllAppsRecyclerView) rv;
+ mRecyclerView.setEdgeEffectFactory(createEdgeEffectFactory());
+ mRecyclerView.setApps(mAppsList);
+ mRecyclerView.setLayoutManager(mLayoutManager);
+ mRecyclerView.setAdapter(mAdapter);
+ mRecyclerView.setHasFixedSize(true);
+ // No animations will occur when changes occur to the items in this RecyclerView.
+ mRecyclerView.setItemAnimator(null);
+ mRecyclerView.addOnScrollListener(mScrollListener);
+ FocusedItemDecorator focusedItemDecorator = new FocusedItemDecorator(mRecyclerView);
+ mRecyclerView.addItemDecoration(focusedItemDecorator);
+ mAdapter.setIconFocusListener(focusedItemDecorator.getFocusListener());
+ applyPadding();
+ }
+
+ void applyPadding() {
+ if (mRecyclerView != null) {
+ int bottomOffset = 0;
+ if (isWork() && mWorkManager.getWorkModeSwitch() != null) {
+ bottomOffset = mInsets.bottom + mWorkManager.getWorkModeSwitch().getHeight();
+ }
+ mRecyclerView.setPadding(mPadding.left, mPadding.top, mPadding.right,
+ mPadding.bottom + bottomOffset);
+ }
+ }
+
+ private boolean isWork() {
+ return mType == WORK;
+ }
+
+ private boolean isSearch() {
+ return mType == SEARCH;
+ }
+ }
}
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index 72f14a872e..515f80af01 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -33,6 +33,7 @@ import androidx.recyclerview.widget.RecyclerView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
+import com.android.launcher3.allapps.BaseAllAppsContainerView.AdapterHolder;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.views.ActivityContext;
@@ -54,11 +55,10 @@ public class FloatingHeaderView extends LinearLayout implements
private final RecyclerView.OnScrollListener mOnScrollListener =
new RecyclerView.OnScrollListener() {
@Override
- public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
- }
+ public void onScrollStateChanged(@NonNull RecyclerView rv, int newState) {}
@Override
- public void onScrolled(RecyclerView rv, int dx, int dy) {
+ public void onScrolled(@NonNull RecyclerView rv, int dx, int dy) {
if (rv != mCurrentRV) {
return;
}
@@ -90,8 +90,8 @@ public class FloatingHeaderView extends LinearLayout implements
protected ViewGroup mTabLayout;
private AllAppsRecyclerView mMainRV;
private AllAppsRecyclerView mWorkRV;
+ private SearchRecyclerView mSearchRV;
private AllAppsRecyclerView mCurrentRV;
- private ViewGroup mParent;
public boolean mHeaderCollapsed;
protected int mSnappedScrolledY;
private int mTranslationY;
@@ -100,7 +100,6 @@ public class FloatingHeaderView extends LinearLayout implements
protected boolean mTabsHidden;
protected int mMaxTranslation;
- private boolean mMainRVActive = true;
private boolean mCollapsed = false;
@@ -164,12 +163,20 @@ public class FloatingHeaderView extends LinearLayout implements
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- if (mMainRV != null) {
- mTabLayout.getLayoutParams().width = mMainRV.getTabWidth();
- }
+ mTabLayout.getLayoutParams().width = getTabWidth();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
+ /**
+ * Returns distance between left and right app icons
+ */
+ public int getTabWidth() {
+ DeviceProfile grid = ActivityContext.lookupContext(getContext()).getDeviceProfile();
+ int totalWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
+ int iconPadding = totalWidth / grid.numShownAllAppsColumns - grid.allAppsIconSizePx;
+ return totalWidth - iconPadding - grid.allAppsIconDrawablePaddingPx;
+ }
+
private void recreateAllRowsArray() {
int pluginCount = mPluginRows.size();
if (pluginCount == 0) {
@@ -232,7 +239,8 @@ public class FloatingHeaderView extends LinearLayout implements
return super.getFocusedChild();
}
- void setup(AllAppsRecyclerView mainRV, AllAppsRecyclerView workRV, boolean tabsHidden) {
+ void setup(AllAppsRecyclerView mainRV, AllAppsRecyclerView workRV, SearchRecyclerView searchRV,
+ int activeRV, boolean tabsHidden) {
for (FloatingHeaderRow row : mAllRows) {
row.setup(this, mAllRows, tabsHidden);
}
@@ -240,18 +248,27 @@ public class FloatingHeaderView extends LinearLayout implements
mTabsHidden = tabsHidden;
mTabLayout.setVisibility(tabsHidden ? View.GONE : View.VISIBLE);
- mMainRV = setupRV(mMainRV, mainRV);
- mWorkRV = setupRV(mWorkRV, workRV);
- mParent = (ViewGroup) mMainRV.getParent();
- setMainActive(mMainRVActive || mWorkRV == null);
+ mMainRV = mainRV;
+ mWorkRV = workRV;
+ mSearchRV = searchRV;
+ setActiveRV(activeRV);
reset(false);
}
- private AllAppsRecyclerView setupRV(AllAppsRecyclerView old, AllAppsRecyclerView updated) {
- if (old != updated && updated != null) {
- updated.addOnScrollListener(mOnScrollListener);
+ /** Whether this header has been set up previously. */
+ boolean isSetUp() {
+ return mMainRV != null;
+ }
+
+ /** Set the active AllApps RV which will adjust the alpha of the header when scrolled. */
+ void setActiveRV(int rvType) {
+ if (mCurrentRV != null) {
+ mCurrentRV.removeOnScrollListener(mOnScrollListener);
}
- return updated;
+ mCurrentRV =
+ rvType == AdapterHolder.MAIN ? mMainRV
+ : rvType == AdapterHolder.WORK ? mWorkRV : mSearchRV;
+ mCurrentRV.addOnScrollListener(mOnScrollListener);
}
private void updateExpectedHeight() {
@@ -267,11 +284,6 @@ public class FloatingHeaderView extends LinearLayout implements
}
}
- public void setMainActive(boolean active) {
- mCurrentRV = active ? mMainRV : mWorkRV;
- mMainRVActive = active;
- }
-
public int getMaxTranslation() {
if (mMaxTranslation == 0 && mTabsHidden) {
return getResources().getDimensionPixelSize(R.dimen.all_apps_search_bar_bottom_padding);
@@ -332,10 +344,15 @@ public class FloatingHeaderView extends LinearLayout implements
mHeaderClip.top = clipTop;
// clipping on a draw might cause additional redraw
setClipBounds(mHeaderClip);
- mMainRV.setClipBounds(mRVClip);
+ if (mMainRV != null) {
+ mMainRV.setClipBounds(mRVClip);
+ }
if (mWorkRV != null) {
mWorkRV.setClipBounds(mRVClip);
}
+ if (mSearchRV != null) {
+ mSearchRV.setClipBounds(mRVClip);
+ }
}
/**
@@ -402,8 +419,8 @@ public class FloatingHeaderView extends LinearLayout implements
}
private void calcOffset(Point p) {
- p.x = getLeft() - mCurrentRV.getLeft() - mParent.getLeft();
- p.y = getTop() - mCurrentRV.getTop() - mParent.getTop();
+ p.x = getLeft() - mCurrentRV.getLeft() - ((ViewGroup) mCurrentRV.getParent()).getLeft();
+ p.y = getTop() - mCurrentRV.getTop() - ((ViewGroup) mCurrentRV.getParent()).getTop();
}
public boolean hasVisibleContent() {
diff --git a/src/com/android/launcher3/allapps/SearchRecyclerView.java b/src/com/android/launcher3/allapps/SearchRecyclerView.java
new file mode 100644
index 0000000000..482bd296f0
--- /dev/null
+++ b/src/com/android/launcher3/allapps/SearchRecyclerView.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 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.allapps;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import com.android.launcher3.views.RecyclerViewFastScroller;
+
+/** A RecyclerView for AllApps Search results. */
+public class SearchRecyclerView extends AllAppsRecyclerView {
+ private static final String TAG = "SearchRecyclerView";
+
+ public SearchRecyclerView(Context context) {
+ this(context, null);
+ }
+
+ public SearchRecyclerView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public SearchRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public SearchRecyclerView(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ @Override
+ protected void updatePoolSize() {
+ RecycledViewPool pool = getRecycledViewPool();
+ pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_ICON, mNumAppsPerRow);
+ // TODO(b/206905515): Add maxes for other View types.
+ }
+
+ @Override
+ public boolean supportsFastScrolling() {
+ return false;
+ }
+
+ @Override
+ public RecyclerViewFastScroller getScrollbar() {
+ return null;
+ }
+}
diff --git a/src/com/android/launcher3/allapps/WorkEduCard.java b/src/com/android/launcher3/allapps/WorkEduCard.java
index c3364962ef..836cd5af93 100644
--- a/src/com/android/launcher3/allapps/WorkEduCard.java
+++ b/src/com/android/launcher3/allapps/WorkEduCard.java
@@ -71,7 +71,7 @@ public class WorkEduCard extends FrameLayout implements
super.onFinishInflate();
findViewById(R.id.action_btn).setOnClickListener(this);
MarginLayoutParams lp = ((MarginLayoutParams) findViewById(R.id.wrapper).getLayoutParams());
- lp.width = mActivityContext.getAppsView().getActiveRecyclerView().getTabWidth();
+ lp.width = mActivityContext.getAppsView().getFloatingHeaderView().getTabWidth();
}
@Override
diff --git a/src/com/android/launcher3/allapps/WorkProfileManager.java b/src/com/android/launcher3/allapps/WorkProfileManager.java
index dc9f18ca4c..b70cb13b07 100644
--- a/src/com/android/launcher3/allapps/WorkProfileManager.java
+++ b/src/com/android/launcher3/allapps/WorkProfileManager.java
@@ -160,7 +160,7 @@ public class WorkProfileManager implements PersonalWorkSlidingTabStrip.OnActiveP
lp.bottomMargin = workFabMarginBottom;
int totalScreenWidth = mDeviceProfile.widthPx;
int personalWorkTabWidth =
- mAllApps.mActivityContext.getAppsView().getActiveRecyclerView().getTabWidth();
+ mAllApps.mActivityContext.getAppsView().getFloatingHeaderView().getTabWidth();
lp.rightMargin = lp.leftMargin = (totalScreenWidth - personalWorkTabWidth) / 2;
if (mWorkModeSwitch.getParent() != mAllApps) {
mAllApps.addView(mWorkModeSwitch);
diff --git a/src/com/android/launcher3/views/RecyclerViewFastScroller.java b/src/com/android/launcher3/views/RecyclerViewFastScroller.java
index 7a8e9d520e..a6b13a099f 100644
--- a/src/com/android/launcher3/views/RecyclerViewFastScroller.java
+++ b/src/com/android/launcher3/views/RecyclerViewFastScroller.java
@@ -45,7 +45,7 @@ import android.widget.TextView;
import androidx.annotation.RequiresApi;
import androidx.recyclerview.widget.RecyclerView;
-import com.android.launcher3.BaseRecyclerView;
+import com.android.launcher3.FastScrollRecyclerView;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.graphics.FastScrollThumbDrawable;
@@ -129,7 +129,7 @@ public class RecyclerViewFastScroller extends View {
private String mPopupSectionName;
private Insets mSystemGestureInsets;
- protected BaseRecyclerView mRv;
+ protected FastScrollRecyclerView mRv;
private RecyclerView.OnScrollListener mOnScrollListener;
private int mDownX;
@@ -174,7 +174,7 @@ public class RecyclerViewFastScroller extends View {
ta.recycle();
}
- public void setRecyclerView(BaseRecyclerView rv, TextView popupView) {
+ public void setRecyclerView(FastScrollRecyclerView rv, TextView popupView) {
if (mRv != null && mOnScrollListener != null) {
mRv.removeOnScrollListener(mOnScrollListener);
}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
index 755e4a9085..bdf646bfaf 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
@@ -27,8 +27,8 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener;
-import com.android.launcher3.BaseRecyclerView;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.FastScrollRecyclerView;
import com.android.launcher3.R;
import com.android.launcher3.views.ActivityContext;
import com.android.launcher3.widget.model.WidgetListSpaceEntry;
@@ -41,7 +41,7 @@ import com.android.launcher3.widget.picker.WidgetsSpaceViewHolderBinder.EmptySpa
/**
* The widgets recycler view.
*/
-public class WidgetsRecyclerView extends BaseRecyclerView implements OnItemTouchListener {
+public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnItemTouchListener {
private WidgetsListAdapter mAdapter;
diff --git a/tests/src/com/android/launcher3/ui/WorkProfileTest.java b/tests/src/com/android/launcher3/ui/WorkProfileTest.java
index 7c1be1de09..35b4ca6431 100644
--- a/tests/src/com/android/launcher3/ui/WorkProfileTest.java
+++ b/tests/src/com/android/launcher3/ui/WorkProfileTest.java
@@ -140,8 +140,8 @@ public class WorkProfileTest extends AbstractLauncherUiTest {
executeOnLauncher(l -> {
ActivityAllAppsContainerView> allApps = l.getAppsView();
assertEquals("Work tab is not focused", allApps.getCurrentPage(), WORK_PAGE);
- View workPausedCard = allApps.getActiveRecyclerView().findViewHolderForAdapterPosition(
- 0).itemView;
+ View workPausedCard = allApps.getActiveRecyclerView()
+ .findViewHolderForAdapterPosition(0).itemView;
workPausedCard.findViewById(R.id.enable_work_apps).performClick();
});
waitForLauncherCondition("Work profile toggle ON failed", launcher -> {