Merge "Moves Search results into a separate RV (take 2)." into tm-dev

This commit is contained in:
Andy Wickham
2022-05-26 21:41:55 +00:00
committed by Android (Google) Code Review
18 changed files with 392 additions and 212 deletions

View File

@@ -33,6 +33,10 @@
layout="@layout/all_apps_bottom_sheet_background"
android:visibility="gone" />
<include
layout="@layout/search_results_rv_layout"
android:visibility="gone" />
<include
layout="@layout/all_apps_rv_layout"
android:visibility="gone" />

View File

@@ -44,9 +44,10 @@ public class TaskbarAllAppsContainerView extends
}
@Override
protected BaseAllAppsAdapter getAdapter(AlphabeticalAppsList<TaskbarAllAppsContext> mAppsList,
protected BaseAllAppsAdapter<TaskbarAllAppsContext> createAdapter(
AlphabeticalAppsList<TaskbarAllAppsContext> appsList,
BaseAdapterProvider[] adapterProviders) {
return new AllAppsGridAdapter<>(mActivityContext, getLayoutInflater(), mAppsList,
return new AllAppsGridAdapter<>(mActivityContext, getLayoutInflater(), appsList,
adapterProviders);
}
}

View File

@@ -29,6 +29,10 @@
layout="@layout/all_apps_bottom_sheet_background"
android:visibility="gone" />
<include
layout="@layout/search_results_rv_layout"
android:visibility="gone" />
<include
layout="@layout/all_apps_rv_layout"
android:visibility="gone" />

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<com.android.launcher3.allapps.SearchRecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/search_results_list_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
android:focusable="true" />

View File

@@ -59,6 +59,10 @@
layout="@layout/all_apps_bottom_sheet_background"
android:visibility="gone" />
<include
layout="@layout/search_results_rv_layout"
android:visibility="gone" />
<include
layout="@layout/all_apps_rv_layout"
android:visibility="gone" />

View File

@@ -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;
* <li> Enable fast scroller.
* </ul>
*/
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);
}
}
}

View File

@@ -82,7 +82,7 @@ public class ActivityAllAppsContainerView<T extends Context & AppLauncher
OnClickListener marketSearchClickListener = (v) -> 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<T extends Context & AppLauncher
* Sets results list for search
*/
public void setSearchResults(ArrayList<AdapterItem> 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<T extends Context & AppLauncher
@Override
public String getDescription() {
if (!mUsingTabs && mIsSearching) {
if (!mUsingTabs && isSearching()) {
return getContext().getString(R.string.all_apps_search_results);
} else {
return super.getDescription();
@@ -156,8 +156,13 @@ public class ActivityAllAppsContainerView<T extends Context & AppLauncher
}
@Override
protected boolean showTabs() {
return super.showTabs() && !mIsSearching;
protected boolean shouldShowTabs() {
return super.shouldShowTabs() && !isSearching();
}
@Override
public boolean isSearching() {
return mIsSearching;
}
@Override
@@ -179,15 +184,19 @@ public class ActivityAllAppsContainerView<T extends Context & AppLauncher
}
@Override
protected View replaceRVContainer(boolean showTabs) {
View rvContainer = super.replaceRVContainer(showTabs);
protected View replaceAppsRVContainer(boolean showTabs) {
View rvContainer = super.replaceAppsRVContainer(showTabs);
removeCustomRules(rvContainer);
removeCustomRules(getSearchRecyclerView());
if (FeatureFlags.ENABLE_FLOATING_SEARCH_BAR.get()) {
alignParentTop(rvContainer, showTabs);
alignParentTop(getSearchRecyclerView(), /* tabs= */ false);
layoutAboveSearchContainer(rvContainer);
layoutAboveSearchContainer(getSearchRecyclerView());
} else {
layoutBelowSearchContainer(rvContainer, showTabs);
layoutBelowSearchContainer(getSearchRecyclerView(), /* tabs= */ false);
}
return rvContainer;
@@ -214,7 +223,7 @@ public class ActivityAllAppsContainerView<T extends Context & AppLauncher
float prog = Utilities.boundToRange((float) scrolledOffset / mHeaderThreshold, 0f, 1f);
boolean bgVisible = mSearchUiManager.getBackgroundVisibility();
if (scrolledOffset == 0 && !mIsSearching) {
if (scrolledOffset == 0 && !isSearching()) {
bgVisible = true;
} else if (scrolledOffset > mHeaderThreshold) {
bgVisible = false;
@@ -248,7 +257,7 @@ public class ActivityAllAppsContainerView<T extends Context & AppLauncher
int topMargin = getContext().getResources().getDimensionPixelSize(
R.dimen.all_apps_header_top_margin);
if (includeTabsMargin) {
topMargin = topMargin + getContext().getResources().getDimensionPixelSize(
topMargin += getContext().getResources().getDimensionPixelSize(
R.dimen.all_apps_header_pill_height);
}
layoutParams.topMargin = topMargin;
@@ -289,9 +298,9 @@ public class ActivityAllAppsContainerView<T extends Context & AppLauncher
}
@Override
protected BaseAllAppsAdapter getAdapter(AlphabeticalAppsList<T> mAppsList,
protected BaseAllAppsAdapter<T> createAdapter(AlphabeticalAppsList<T> appsList,
BaseAdapterProvider[] adapterProviders) {
return new AllAppsGridAdapter<>(mActivityContext, getLayoutInflater(), mAppsList,
return new AllAppsGridAdapter<>(mActivityContext, getLayoutInflater(), appsList,
adapterProviders);
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}

View File

@@ -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<T extends Context & ActivityContext> implement
// The set of apps from the system
private final List<AppInfo> mApps = new ArrayList<>();
@Nullable
private final AllAppsStore mAllAppsStore;
// The number of results in current adapter
@@ -89,14 +91,16 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement
private int mNumAppRowsInAdapter;
private Predicate<ItemInfo> 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<ItemInfo> itemFilter) {
@@ -162,9 +166,9 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> 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<T extends Context & ActivityContext> 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<T extends Context & ActivityContext> implement
*/
@Override
public void onAppsUpdated() {
if (mAllAppsStore == null) {
return;
}
// Sort the list of apps
mApps.clear();
Stream<AppInfo> 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<T extends Context & ActivityContext> 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<T extends Context & ActivityContext> 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();

View File

@@ -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<T extends Context & ActivityConte
OnDeviceProfileChangeListener, OnActivePageChangedListener,
ScrimView.ScrimDrawingController {
private static final String BUNDLE_KEY_CURRENT_PAGE = "launcher.allapps.current_page";
protected static final String BUNDLE_KEY_CURRENT_PAGE = "launcher.allapps.current_page";
public static final float PULL_MULTIPLIER = .02f;
public static final float FLING_VELOCITY_MULTIPLIER = 1200f;
@@ -112,6 +113,7 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
private int mNavBarScrimHeight = 0;
private AllAppsPagedView mViewPager;
private SearchRecyclerView mSearchRecyclerView;
protected FloatingHeaderView mHeader;
private View mBottomSheetBackground;
@@ -144,9 +146,10 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
mActivityContext.getSystemService(UserManager.class),
this,
Utilities.getPrefs(mActivityContext), mActivityContext.getDeviceProfile());
mAH = Arrays.asList(null, null);
mAH.set(AdapterHolder.MAIN, new AdapterHolder(false /* isWork */));
mAH.set(AdapterHolder.WORK, new AdapterHolder(true /* isWork */));
mAH = Arrays.asList(null, null, null);
mAH.set(AdapterHolder.MAIN, new AdapterHolder(AdapterHolder.MAIN));
mAH.set(AdapterHolder.WORK, new AdapterHolder(AdapterHolder.WORK));
mAH.set(AdapterHolder.SEARCH, new AdapterHolder(AdapterHolder.SEARCH));
mNavBarScrimPaint = new Paint();
mNavBarScrimPaint.setColor(Themes.getAttrColor(context, R.attr.allAppsNavBarScrimColor));
@@ -178,7 +181,7 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
Bundle state = (Bundle) sparseArray.get(R.id.work_tab_state_id, null);
if (state != null) {
int currentPage = state.getInt(BUNDLE_KEY_CURRENT_PAGE, 0);
if (currentPage != 0 && mViewPager != null) {
if (currentPage == AdapterHolder.WORK && mViewPager != null) {
mViewPager.setCurrentPage(currentPage);
rebindAdapters();
} else {
@@ -201,7 +204,7 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
*/
public void setOnIconLongClickListener(OnLongClickListener listener) {
for (AdapterHolder holder : mAH) {
holder.adapter.setOnIconLongClickListener(listener);
holder.mAdapter.setOnIconLongClickListener(listener);
}
}
@@ -216,7 +219,7 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
@Override
public void onDeviceProfileChanged(DeviceProfile dp) {
for (AdapterHolder holder : mAH) {
holder.adapter.setAppsPerRow(dp.numShownAllAppsColumns);
holder.mAdapter.setAppsPerRow(dp.numShownAllAppsColumns);
if (holder.mRecyclerView != null) {
// Remove all views and clear the pool, while keeping the data same. After this
// call, all the viewHolders will be recreated.
@@ -233,7 +236,7 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
private void onAppsUpdated() {
mHasWorkApps = Stream.of(mAllAppsStore.getApps()).anyMatch(mWorkManager.getMatcher());
if (!mAH.get(AdapterHolder.MAIN).mAppsList.hasFilter()) {
if (!isSearching()) {
rebindAdapters();
if (mHasWorkApps) {
mWorkManager.reset();
@@ -245,30 +248,32 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
* Returns whether the view itself will handle the touch event or not.
*/
public boolean shouldContainerScroll(MotionEvent ev) {
BaseDragLayer dragLayer = mActivityContext.getDragLayer();
// Scroll if not within the container view (e.g. over large-screen scrim).
if (!mActivityContext.getDragLayer().isEventOverView(this, ev)) {
if (!dragLayer.isEventOverView(this, ev)) {
return true;
}
if (mActivityContext.getDragLayer().isEventOverView(mBottomSheetHandleArea, ev)) {
if (dragLayer.isEventOverView(mBottomSheetHandleArea, ev)) {
return true;
}
AllAppsRecyclerView rv = getActiveRecyclerView();
if (rv == null) {
return true;
}
if (rv.getScrollbar().getThumbOffsetY() >= 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<T extends Context & ActivityConte
public boolean onTouchEvent(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;
@@ -316,8 +321,16 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
return getContext().getString(R.string.all_apps_button_label);
}
/** The current recycler view visible in the container. */
/** The current active recycler view (A-Z list from one of the profiles, or search results). */
public AllAppsRecyclerView getActiveRecyclerView() {
if (isSearching()) {
return getSearchRecyclerView();
}
return getActiveAppsRecyclerView();
}
/** The current apps recycler view in the container. */
private AllAppsRecyclerView getActiveAppsRecyclerView() {
if (!mUsingTabs || isPersonalTab()) {
return mAH.get(AdapterHolder.MAIN).mRecyclerView;
} else {
@@ -325,6 +338,19 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
}
}
/**
* The container for A-Z apps (the ViewPager for main+work tabs, or main RV). This is currently
* hidden while searching.
**/
private View getAppsRecyclerViewContainer() {
return mViewPager != null ? mViewPager : findViewById(R.id.apps_list_view);
}
/** The RV for search results, which is hidden while A-Z apps are visible. */
public SearchRecyclerView getSearchRecyclerView() {
return mSearchRecyclerView;
}
protected boolean isPersonalTab() {
return mViewPager == null || mViewPager.getNextPage() == 0;
}
@@ -372,6 +398,9 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
});
mHeader = findViewById(R.id.all_apps_header);
mSearchRecyclerView = findViewById(R.id.search_results_list_view);
mAH.get(AdapterHolder.SEARCH).setup(mSearchRecyclerView,
/* Filter out A-Z apps */ itemInfo -> false);
rebindAdapters(true /* force */);
mBottomSheetBackground = findViewById(R.id.bottom_sheet_background);
@@ -388,7 +417,7 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
mInsets.set(insets);
DeviceProfile grid = mActivityContext.getDeviceProfile();
applyAdapterPaddings(grid);
applyAdapterSideAndBottomPaddings(grid);
MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
mlp.leftMargin = insets.left;
@@ -415,7 +444,7 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
@Override
public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
mNavBarScrimHeight = getNavBarScrimHeight(insets);
applyAdapterPaddings(mActivityContext.getDeviceProfile());
applyAdapterSideAndBottomPaddings(mActivityContext.getDeviceProfile());
return super.dispatchApplyWindowInsets(insets);
}
@@ -434,15 +463,23 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
}
protected void rebindAdapters(boolean force) {
boolean showTabs = showTabs();
updateSearchResultsVisibility();
boolean showTabs = shouldShowTabs();
if (showTabs == mUsingTabs && !force) {
return;
}
// replaceRVcontainer() needs to use both mUsingTabs value to remove the old view AND
if (isSearching()) {
mUsingTabs = showTabs;
mWorkManager.detachWorkModeSwitch();
return;
}
// replaceAppsRVcontainer() needs to use both mUsingTabs value to remove the old view AND
// showTabs value to create new view. Hence the mUsingTabs new value assignment MUST happen
// after this call.
replaceRVContainer(showTabs);
replaceAppsRVContainer(showTabs);
mUsingTabs = showTabs;
mAllAppsStore.unregisterIconContainer(mAH.get(AdapterHolder.MAIN).mRecyclerView);
@@ -483,13 +520,27 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
mAllAppsStore.registerIconContainer(mAH.get(AdapterHolder.WORK).mRecyclerView);
}
private void applyAdapterPaddings(DeviceProfile grid) {
int bottomPadding = Math.max(mInsets.bottom, mNavBarScrimHeight);
for (int i = 0; i < mAH.size(); i++) {
mAH.get(i).mPadding.bottom = bottomPadding;
mAH.get(i).mPadding.left = mAH.get(i).mPadding.right = grid.allAppsLeftRightPadding;
mAH.get(i).applyPadding();
private void updateSearchResultsVisibility() {
if (isSearching()) {
getSearchRecyclerView().setVisibility(VISIBLE);
getAppsRecyclerViewContainer().setVisibility(GONE);
} else {
getSearchRecyclerView().setVisibility(GONE);
getAppsRecyclerViewContainer().setVisibility(VISIBLE);
}
if (mHeader.isSetUp()) {
mHeader.setActiveRV(getCurrentPage());
}
}
private void applyAdapterSideAndBottomPaddings(DeviceProfile grid) {
int bottomPadding = Math.max(mInsets.bottom, mNavBarScrimHeight);
mAH.forEach(adapterHolder -> {
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<T extends Context & ActivityConte
}
}
protected boolean showTabs() {
protected boolean shouldShowTabs() {
return mHasWorkApps;
}
protected View replaceRVContainer(boolean showTabs) {
for (AdapterHolder adapterHolder : mAH) {
protected boolean isSearching() {
return false;
}
protected View replaceAppsRVContainer(boolean showTabs) {
for (int i = AdapterHolder.MAIN; i <= AdapterHolder.WORK; i++) {
AdapterHolder adapterHolder = mAH.get(i);
if (adapterHolder.mRecyclerView != null) {
adapterHolder.mRecyclerView.setLayoutManager(null);
adapterHolder.mRecyclerView.setAdapter(null);
}
}
View oldView = getRecyclerViewContainer();
View oldView = getAppsRecyclerViewContainer();
int index = indexOfChild(oldView);
removeView(oldView);
int layout = showTabs ? R.layout.all_apps_tabs : R.layout.all_apps_rv_layout;
@@ -534,13 +590,8 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
return newView;
}
public View getRecyclerViewContainer() {
return mViewPager != null ? mViewPager : findViewById(R.id.apps_list_view);
}
@Override
public void onActivePageChanged(int currentActivePage) {
mHeader.setMainActive(currentActivePage == AdapterHolder.MAIN);
if (mAH.get(currentActivePage).mRecyclerView != null) {
mAH.get(currentActivePage).mRecyclerView.bindFastScrollbar();
}
@@ -569,8 +620,8 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
return isDescendantViewVisible(R.id.tab_work);
}
public AlphabeticalAppsList<T> getApps() {
return mAH.get(AdapterHolder.MAIN).mAppsList;
public AlphabeticalAppsList<T> getSearchResultList() {
return mAH.get(AdapterHolder.SEARCH).mAppsList;
}
public FloatingHeaderView getFloatingHeaderView() {
@@ -579,35 +630,40 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
@VisibleForTesting
public View getContentView() {
return mViewPager == null ? getActiveRecyclerView() : mViewPager;
return isSearching() ? getSearchRecyclerView() : getAppsRecyclerViewContainer();
}
/** The current page visible in all apps. */
public int getCurrentPage() {
return mViewPager != null ? mViewPager.getCurrentPage() : AdapterHolder.MAIN;
return isSearching()
? AdapterHolder.SEARCH
: mViewPager == null ? AdapterHolder.MAIN : mViewPager.getNextPage();
}
/** The scroll bar for the active recycler view. */
/** The scroll bar for the active apps recycler view. */
public RecyclerViewFastScroller getScrollBar() {
AllAppsRecyclerView rv = getActiveRecyclerView();
AllAppsRecyclerView rv = getActiveAppsRecyclerView();
return rv == null ? null : rv.getScrollbar();
}
void setupHeader() {
mHeader.setVisibility(View.VISIBLE);
boolean tabsHidden = !mUsingTabs;
mHeader.setup(
mAH.get(AdapterHolder.MAIN).mRecyclerView,
mAH.get(AdapterHolder.WORK).mRecyclerView,
mAH.get(AdapterHolder.WORK).mRecyclerView == null);
(SearchRecyclerView) mAH.get(AdapterHolder.SEARCH).mRecyclerView,
getCurrentPage(),
tabsHidden);
int padding = mHeader.getMaxTranslation();
for (int i = 0; i < mAH.size(); i++) {
mAH.get(i).mPadding.top = padding;
mAH.get(i).applyPadding();
if (mAH.get(i).mRecyclerView != null) {
mAH.get(i).mRecyclerView.scrollToTop();
mAH.forEach(adapterHolder -> {
adapterHolder.mPadding.top = padding;
adapterHolder.applyPadding();
if (adapterHolder.mRecyclerView != null) {
adapterHolder.mRecyclerView.scrollToTop();
}
}
});
}
public boolean isHeaderVisible() {
@@ -623,7 +679,7 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
float distance = (float) ((1 - progress) * getHeight()); // px
float distance = (1 - progress) * getHeight(); // px
float settleVelocity = Math.min(0, distance
/ (AllAppsTransitionController.INTERP_COEFF * animator.getDuration())
+ velocity);
@@ -702,73 +758,83 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
return ColorUtils.blendARGB(mScrimColor, mHeaderProtectionColor, blendRatio);
}
protected abstract BaseAllAppsAdapter getAdapter(AlphabeticalAppsList<T> mAppsList,
protected abstract BaseAllAppsAdapter<T> createAdapter(AlphabeticalAppsList<T> 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<T> adapter;
final RecyclerView.LayoutManager mLayoutManager;
final AlphabeticalAppsList<T> 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<ItemInfo> 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<T> mAdapter;
final RecyclerView.LayoutManager mLayoutManager;
final AlphabeticalAppsList<T> 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<ItemInfo> 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;
}
}
}

View File

@@ -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() {

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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 -> {