diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java index 37cd753ba4..b36b9f1ffd 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java @@ -25,9 +25,6 @@ import android.view.WindowInsets; import androidx.recyclerview.widget.RecyclerView; import com.android.launcher3.allapps.AllAppsGridAdapter; -import com.android.launcher3.allapps.AlphabeticalAppsList; -import com.android.launcher3.allapps.BaseAdapterProvider; -import com.android.launcher3.allapps.BaseAllAppsAdapter; import com.android.launcher3.allapps.BaseAllAppsContainerView; import com.android.launcher3.allapps.search.SearchAdapterProvider; @@ -82,11 +79,4 @@ public class TaskbarAllAppsContainerView extends BaseAllAppsContainerView mAppsList, - BaseAdapterProvider[] adapterProviders) { - return new AllAppsGridAdapter<>(mActivityContext, getLayoutInflater(), mAppsList, - adapterProviders); - } } diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java index b94a61251b..114f8130c7 100644 --- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java @@ -256,11 +256,4 @@ public class ActivityAllAppsContainerView extend layoutParams.removeRule(RelativeLayout.BELOW); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP); } - - @Override - protected BaseAllAppsAdapter getAdapter(AlphabeticalAppsList mAppsList, - BaseAdapterProvider[] adapterProviders) { - return new AllAppsGridAdapter<>(mActivityContext, getLayoutInflater(), mAppsList, - adapterProviders); - } } diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java index 58df50ca82..f1ca9c0c99 100644 --- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java +++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java @@ -15,20 +15,36 @@ */ package com.android.launcher3.allapps; +import static com.android.launcher3.touch.ItemLongClickListener.INSTANCE_ALL_APPS; + import android.content.Context; +import android.content.res.Resources; +import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; +import android.view.View.OnClickListener; +import android.view.View.OnFocusChangeListener; +import android.view.View.OnLongClickListener; import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; +import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.core.view.accessibility.AccessibilityEventCompat; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.core.view.accessibility.AccessibilityRecordCompat; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import com.android.launcher3.BubbleTextView; +import com.android.launcher3.R; +import com.android.launcher3.config.FeatureFlags; +import com.android.launcher3.model.data.AppInfo; +import com.android.launcher3.model.data.ItemInfoWithIcon; import com.android.launcher3.views.ActivityContext; +import java.util.Arrays; import java.util.List; /** @@ -37,26 +53,111 @@ import java.util.List; * @param Type of context inflating all apps. */ public class AllAppsGridAdapter extends - BaseAllAppsAdapter { + RecyclerView.Adapter { public static final String TAG = "AppsGridAdapter"; - private final GridLayoutManager mGridLayoutMgr; - private final GridSpanSizer mGridSizer; - public AllAppsGridAdapter(T activityContext, LayoutInflater inflater, - AlphabeticalAppsList apps, BaseAdapterProvider[] adapterProviders) { - super(activityContext, inflater, apps, adapterProviders); - mGridSizer = new GridSpanSizer(); - mGridLayoutMgr = new AppsGridLayoutManager(mActivityContext); - mGridLayoutMgr.setSpanSizeLookup(mGridSizer); - setAppsPerRow(activityContext.getDeviceProfile().numShownAllAppsColumns); + // A normal icon + public static final int VIEW_TYPE_ICON = 1 << 1; + // The message shown when there are no filtered results + public static final int VIEW_TYPE_EMPTY_SEARCH = 1 << 2; + // The message to continue to a market search when there are no filtered results + public static final int VIEW_TYPE_SEARCH_MARKET = 1 << 3; + + // We use various dividers for various purposes. They share enough attributes to reuse layouts, + // but differ in enough attributes to require different view types + + // A divider that separates the apps list and the search market button + public static final int VIEW_TYPE_ALL_APPS_DIVIDER = 1 << 4; + + // Common view type masks + public static final int VIEW_TYPE_MASK_DIVIDER = VIEW_TYPE_ALL_APPS_DIVIDER; + public static final int VIEW_TYPE_MASK_ICON = VIEW_TYPE_ICON; + + + private final BaseAdapterProvider[] mAdapterProviders; + + /** + * ViewHolder for each icon. + */ + public static class ViewHolder extends RecyclerView.ViewHolder { + + public ViewHolder(View v) { + super(v); + } } /** - * Returns the grid layout manager. + * Info about a particular adapter item (can be either section or app) */ - public RecyclerView.LayoutManager getLayoutManager() { - return mGridLayoutMgr; + public static class AdapterItem { + /** Common properties */ + // The index of this adapter item in the list + public int position; + // The type of this item + public int viewType; + + // The section name of this item. Note that there can be multiple items with different + // sectionNames in the same section + public String sectionName = null; + // The row that this item shows up on + public int rowIndex; + // The index of this app in the row + public int rowAppIndex; + // The associated ItemInfoWithIcon for the item + public ItemInfoWithIcon itemInfo = null; + // The index of this app not including sections + public int appIndex = -1; + // Search section associated to result + public DecorationInfo decorationInfo = null; + + /** + * Factory method for AppIcon AdapterItem + */ + public static AdapterItem asApp(int pos, String sectionName, AppInfo appInfo, + int appIndex) { + AdapterItem item = new AdapterItem(); + item.viewType = VIEW_TYPE_ICON; + item.position = pos; + item.sectionName = sectionName; + item.itemInfo = appInfo; + item.appIndex = appIndex; + return item; + } + + /** + * Factory method for empty search results view + */ + public static AdapterItem asEmptySearch(int pos) { + AdapterItem item = new AdapterItem(); + item.viewType = VIEW_TYPE_EMPTY_SEARCH; + item.position = pos; + return item; + } + + /** + * Factory method for a dividerView in AllAppsSearch + */ + public static AdapterItem asAllAppsDivider(int pos) { + AdapterItem item = new AdapterItem(); + item.viewType = VIEW_TYPE_ALL_APPS_DIVIDER; + item.position = pos; + return item; + } + + /** + * Factory method for a market search button + */ + public static AdapterItem asMarketSearch(int pos) { + AdapterItem item = new AdapterItem(); + item.viewType = VIEW_TYPE_SEARCH_MARKET; + item.position = pos; + return item; + } + + protected boolean isCountedForAccessibility() { + return viewType == VIEW_TYPE_ICON || viewType == VIEW_TYPE_SEARCH_MARKET; + } } /** @@ -116,7 +217,7 @@ public class AllAppsGridAdapter extends */ private int getRowsNotForAccessibility(int adapterPosition) { List items = mApps.getAdapterItems(); - adapterPosition = Math.max(adapterPosition, items.size() - 1); + adapterPosition = Math.max(adapterPosition, mApps.getAdapterItems().size() - 1); int extraRows = 0; for (int i = 0; i <= adapterPosition; i++) { if (!isViewType(items.get(i).viewType, VIEW_TYPE_MASK_ICON)) { @@ -127,20 +228,6 @@ public class AllAppsGridAdapter extends } } - @Override - public void setAppsPerRow(int appsPerRow) { - mAppsPerRow = appsPerRow; - int totalSpans = mAppsPerRow; - for (BaseAdapterProvider adapterProvider : mAdapterProviders) { - for (int itemPerRow : adapterProvider.getSupportedItemsPerRowArray()) { - if (totalSpans % itemPerRow != 0) { - totalSpans *= itemPerRow; - } - } - } - mGridLayoutMgr.setSpanCount(totalSpans); - } - /** * Helper class to size the grid items. */ @@ -168,4 +255,202 @@ public class AllAppsGridAdapter extends } } } + + private final T mActivityContext; + private final LayoutInflater mLayoutInflater; + private final AlphabeticalAppsList mApps; + private final GridLayoutManager mGridLayoutMgr; + private final GridSpanSizer mGridSizer; + + private final OnClickListener mOnIconClickListener; + private OnLongClickListener mOnIconLongClickListener = INSTANCE_ALL_APPS; + + private int mAppsPerRow; + + private OnFocusChangeListener mIconFocusListener; + + // The text to show when there are no search results and no market search handler. + protected String mEmptySearchMessage; + // The click listener to send off to the market app, updated each time the search query changes. + private OnClickListener mMarketSearchClickListener; + + private final int mExtraHeight; + + public AllAppsGridAdapter(T activityContext, LayoutInflater inflater, + AlphabeticalAppsList apps, BaseAdapterProvider[] adapterProviders) { + Resources res = activityContext.getResources(); + mActivityContext = activityContext; + mApps = apps; + mEmptySearchMessage = res.getString(R.string.all_apps_loading_message); + mGridSizer = new GridSpanSizer(); + mGridLayoutMgr = new AppsGridLayoutManager(mActivityContext); + mGridLayoutMgr.setSpanSizeLookup(mGridSizer); + mLayoutInflater = inflater; + + mOnIconClickListener = mActivityContext.getItemOnClickListener(); + + mAdapterProviders = adapterProviders; + setAppsPerRow(mActivityContext.getDeviceProfile().numShownAllAppsColumns); + mExtraHeight = mActivityContext.getResources().getDimensionPixelSize( + R.dimen.all_apps_height_extra); + } + + public void setAppsPerRow(int appsPerRow) { + mAppsPerRow = appsPerRow; + int totalSpans = mAppsPerRow; + for (BaseAdapterProvider adapterProvider : mAdapterProviders) { + for (int itemPerRow : adapterProvider.getSupportedItemsPerRowArray()) { + if (totalSpans % itemPerRow != 0) { + totalSpans *= itemPerRow; + } + } + } + mGridLayoutMgr.setSpanCount(totalSpans); + } + + /** + * Sets the long click listener for icons + */ + public void setOnIconLongClickListener(@Nullable OnLongClickListener listener) { + mOnIconLongClickListener = listener; + } + + public static boolean isDividerViewType(int viewType) { + return isViewType(viewType, VIEW_TYPE_MASK_DIVIDER); + } + + public static boolean isIconViewType(int viewType) { + return isViewType(viewType, VIEW_TYPE_MASK_ICON); + } + + public static boolean isViewType(int viewType, int viewTypeMask) { + return (viewType & viewTypeMask) != 0; + } + + public void setIconFocusListener(OnFocusChangeListener focusListener) { + mIconFocusListener = focusListener; + } + + /** + * Sets the last search query that was made, used to show when there are no results and to also + * seed the intent for searching the market. + */ + public void setLastSearchQuery(String query, OnClickListener marketSearchClickListener) { + Resources res = mActivityContext.getResources(); + mEmptySearchMessage = res.getString(R.string.all_apps_no_search_results, query); + mMarketSearchClickListener = marketSearchClickListener; + } + + /** + * Returns the grid layout manager. + */ + public GridLayoutManager getLayoutManager() { + return mGridLayoutMgr; + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + switch (viewType) { + case VIEW_TYPE_ICON: + int layout = !FeatureFlags.ENABLE_TWOLINE_ALLAPPS.get() ? R.layout.all_apps_icon + : R.layout.all_apps_icon_twoline; + BubbleTextView icon = (BubbleTextView) mLayoutInflater.inflate( + layout, parent, false); + icon.setLongPressTimeoutFactor(1f); + icon.setOnFocusChangeListener(mIconFocusListener); + icon.setOnClickListener(mOnIconClickListener); + icon.setOnLongClickListener(mOnIconLongClickListener); + // Ensure the all apps icon height matches the workspace icons in portrait mode. + icon.getLayoutParams().height = + mActivityContext.getDeviceProfile().allAppsCellHeightPx; + if (FeatureFlags.ENABLE_TWOLINE_ALLAPPS.get()) { + icon.getLayoutParams().height += mExtraHeight; + } + return new ViewHolder(icon); + case VIEW_TYPE_EMPTY_SEARCH: + return new ViewHolder(mLayoutInflater.inflate(R.layout.all_apps_empty_search, + parent, false)); + case VIEW_TYPE_SEARCH_MARKET: + View searchMarketView = mLayoutInflater.inflate(R.layout.all_apps_search_market, + parent, false); + searchMarketView.setOnClickListener(mMarketSearchClickListener); + return new ViewHolder(searchMarketView); + case VIEW_TYPE_ALL_APPS_DIVIDER: + return new ViewHolder(mLayoutInflater.inflate( + R.layout.all_apps_divider, parent, false)); + default: + BaseAdapterProvider adapterProvider = getAdapterProvider(viewType); + if (adapterProvider != null) { + return adapterProvider.onCreateViewHolder(mLayoutInflater, parent, viewType); + } + throw new RuntimeException("Unexpected view type" + viewType); + } + } + + @Override + public void onBindViewHolder(ViewHolder holder, int position) { + switch (holder.getItemViewType()) { + case VIEW_TYPE_ICON: + AdapterItem adapterItem = mApps.getAdapterItems().get(position); + BubbleTextView icon = (BubbleTextView) holder.itemView; + icon.reset(); + if (adapterItem.itemInfo instanceof AppInfo) { + icon.applyFromApplicationInfo((AppInfo) adapterItem.itemInfo); + } else { + icon.applyFromItemInfoWithIcon(adapterItem.itemInfo); + } + break; + case VIEW_TYPE_EMPTY_SEARCH: + TextView emptyViewText = (TextView) holder.itemView; + emptyViewText.setText(mEmptySearchMessage); + emptyViewText.setGravity(mApps.hasNoFilteredResults() ? Gravity.CENTER : + Gravity.START | Gravity.CENTER_VERTICAL); + break; + case VIEW_TYPE_SEARCH_MARKET: + TextView searchView = (TextView) holder.itemView; + if (mMarketSearchClickListener != null) { + searchView.setVisibility(View.VISIBLE); + } else { + searchView.setVisibility(View.GONE); + } + break; + case VIEW_TYPE_ALL_APPS_DIVIDER: + // nothing to do + break; + default: + BaseAdapterProvider adapterProvider = getAdapterProvider(holder.getItemViewType()); + if (adapterProvider != null) { + adapterProvider.onBindView(holder, position); + } + } + } + + @Override + public void onViewRecycled(@NonNull ViewHolder holder) { + super.onViewRecycled(holder); + } + + @Override + public boolean onFailedToRecycleView(ViewHolder holder) { + // Always recycle and we will reset the view when it is bound + return true; + } + + @Override + public int getItemCount() { + return mApps.getAdapterItems().size(); + } + + @Override + public int getItemViewType(int position) { + AdapterItem item = mApps.getAdapterItems().get(position); + return item.viewType; + } + + @Nullable + private BaseAdapterProvider getAdapterProvider(int viewType) { + return Arrays.stream(mAdapterProviders).filter( + adapterProvider -> adapterProvider.isViewSupported(viewType)).findFirst().orElse( + null); + } } diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java index a4a58b5f3a..1a1d5211c2 100644 --- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java +++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java @@ -18,7 +18,7 @@ package com.android.launcher3.allapps; import android.content.Context; -import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem; +import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.util.ItemInfoMatcher; @@ -82,7 +82,7 @@ public class AlphabeticalAppsList implement // The of ordered component names as a result of a search query private ArrayList mSearchResults; - private BaseAllAppsAdapter mAdapter; + private AllAppsGridAdapter mAdapter; private AppInfoComparator mAppNameComparator; private final int mNumAppsPerRow; private int mNumAppRowsInAdapter; @@ -106,7 +106,7 @@ public class AlphabeticalAppsList implement /** * Sets the adapter to notify when this dataset changes. */ - public void setAdapter(BaseAllAppsAdapter adapter) { + public void setAdapter(AllAppsGridAdapter adapter) { mAdapter = adapter; } diff --git a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java deleted file mode 100644 index 1d1960d6e2..0000000000 --- a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java +++ /dev/null @@ -1,333 +0,0 @@ -/* - * 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 static com.android.launcher3.touch.ItemLongClickListener.INSTANCE_ALL_APPS; - -import android.content.Context; -import android.content.res.Resources; -import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.View.OnFocusChangeListener; -import android.view.View.OnLongClickListener; -import android.view.ViewGroup; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.recyclerview.widget.RecyclerView; - -import com.android.launcher3.BubbleTextView; -import com.android.launcher3.R; -import com.android.launcher3.config.FeatureFlags; -import com.android.launcher3.model.data.AppInfo; -import com.android.launcher3.model.data.ItemInfoWithIcon; -import com.android.launcher3.views.ActivityContext; - -import java.util.Arrays; - -/** - * Adapter for all the apps. - * - * @param Type of context inflating all apps. - */ -public abstract class BaseAllAppsAdapter extends - RecyclerView.Adapter { - - public static final String TAG = "BaseAllAppsAdapter"; - - // A normal icon - public static final int VIEW_TYPE_ICON = 1 << 1; - // The message shown when there are no filtered results - public static final int VIEW_TYPE_EMPTY_SEARCH = 1 << 2; - // The message to continue to a market search when there are no filtered results - public static final int VIEW_TYPE_SEARCH_MARKET = 1 << 3; - - // We use various dividers for various purposes. They share enough attributes to reuse layouts, - // but differ in enough attributes to require different view types - - // A divider that separates the apps list and the search market button - public static final int VIEW_TYPE_ALL_APPS_DIVIDER = 1 << 4; - - // Common view type masks - public static final int VIEW_TYPE_MASK_DIVIDER = VIEW_TYPE_ALL_APPS_DIVIDER; - public static final int VIEW_TYPE_MASK_ICON = VIEW_TYPE_ICON; - - - protected final BaseAdapterProvider[] mAdapterProviders; - - /** - * ViewHolder for each icon. - */ - public static class ViewHolder extends RecyclerView.ViewHolder { - - public ViewHolder(View v) { - super(v); - } - } - - /** Sets the number of apps to be displayed in one row of the all apps screen. */ - public abstract void setAppsPerRow(int appsPerRow); - - /** - * Info about a particular adapter item (can be either section or app) - */ - public static class AdapterItem { - /** Common properties */ - // The index of this adapter item in the list - public int position; - // The type of this item - public int viewType; - - // The section name of this item. Note that there can be multiple items with different - // sectionNames in the same section - public String sectionName = null; - // The row that this item shows up on - public int rowIndex; - // The index of this app in the row - public int rowAppIndex; - // The associated ItemInfoWithIcon for the item - public ItemInfoWithIcon itemInfo = null; - // The index of this app not including sections - public int appIndex = -1; - // Search section associated to result - public DecorationInfo decorationInfo = null; - - /** - * Factory method for AppIcon AdapterItem - */ - public static AdapterItem asApp(int pos, String sectionName, AppInfo appInfo, - int appIndex) { - AdapterItem item = new AdapterItem(); - item.viewType = VIEW_TYPE_ICON; - item.position = pos; - item.sectionName = sectionName; - item.itemInfo = appInfo; - item.appIndex = appIndex; - return item; - } - - /** - * Factory method for empty search results view - */ - public static AdapterItem asEmptySearch(int pos) { - AdapterItem item = new AdapterItem(); - item.viewType = VIEW_TYPE_EMPTY_SEARCH; - item.position = pos; - return item; - } - - /** - * Factory method for a dividerView in AllAppsSearch - */ - public static AdapterItem asAllAppsDivider(int pos) { - AdapterItem item = new AdapterItem(); - item.viewType = VIEW_TYPE_ALL_APPS_DIVIDER; - item.position = pos; - return item; - } - - /** - * Factory method for a market search button - */ - public static AdapterItem asMarketSearch(int pos) { - AdapterItem item = new AdapterItem(); - item.viewType = VIEW_TYPE_SEARCH_MARKET; - item.position = pos; - return item; - } - - protected boolean isCountedForAccessibility() { - return viewType == VIEW_TYPE_ICON || viewType == VIEW_TYPE_SEARCH_MARKET; - } - } - - protected final T mActivityContext; - protected final AlphabeticalAppsList mApps; - // The text to show when there are no search results and no market search handler. - protected String mEmptySearchMessage; - protected int mAppsPerRow; - - private final LayoutInflater mLayoutInflater; - private final OnClickListener mOnIconClickListener; - private OnLongClickListener mOnIconLongClickListener = INSTANCE_ALL_APPS; - private OnFocusChangeListener mIconFocusListener; - // The click listener to send off to the market app, updated each time the search query changes. - private OnClickListener mMarketSearchClickListener; - private final int mExtraHeight; - - public BaseAllAppsAdapter(T activityContext, LayoutInflater inflater, - AlphabeticalAppsList apps, BaseAdapterProvider[] adapterProviders) { - Resources res = activityContext.getResources(); - mActivityContext = activityContext; - mApps = apps; - mEmptySearchMessage = res.getString(R.string.all_apps_loading_message); - mLayoutInflater = inflater; - - mOnIconClickListener = mActivityContext.getItemOnClickListener(); - - mAdapterProviders = adapterProviders; - mExtraHeight = res.getDimensionPixelSize(R.dimen.all_apps_height_extra); - } - - /** - * Sets the long click listener for icons - */ - public void setOnIconLongClickListener(@Nullable OnLongClickListener listener) { - mOnIconLongClickListener = listener; - } - - /** Checks if the passed viewType represents all apps divider. */ - public static boolean isDividerViewType(int viewType) { - return isViewType(viewType, VIEW_TYPE_MASK_DIVIDER); - } - - /** Checks if the passed viewType represents all apps icon. */ - public static boolean isIconViewType(int viewType) { - return isViewType(viewType, VIEW_TYPE_MASK_ICON); - } - - public void setIconFocusListener(OnFocusChangeListener focusListener) { - mIconFocusListener = focusListener; - } - - /** - * Sets the last search query that was made, used to show when there are no results and to also - * seed the intent for searching the market. - */ - public void setLastSearchQuery(String query, OnClickListener marketSearchClickListener) { - Resources res = mActivityContext.getResources(); - mEmptySearchMessage = res.getString(R.string.all_apps_no_search_results, query); - mMarketSearchClickListener = marketSearchClickListener; - } - - /** - * Returns the layout manager. - */ - public abstract RecyclerView.LayoutManager getLayoutManager(); - - @Override - public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - switch (viewType) { - case VIEW_TYPE_ICON: - int layout = !FeatureFlags.ENABLE_TWOLINE_ALLAPPS.get() ? R.layout.all_apps_icon - : R.layout.all_apps_icon_twoline; - BubbleTextView icon = (BubbleTextView) mLayoutInflater.inflate( - layout, parent, false); - icon.setLongPressTimeoutFactor(1f); - icon.setOnFocusChangeListener(mIconFocusListener); - icon.setOnClickListener(mOnIconClickListener); - icon.setOnLongClickListener(mOnIconLongClickListener); - // Ensure the all apps icon height matches the workspace icons in portrait mode. - icon.getLayoutParams().height = - mActivityContext.getDeviceProfile().allAppsCellHeightPx; - if (FeatureFlags.ENABLE_TWOLINE_ALLAPPS.get()) { - icon.getLayoutParams().height += mExtraHeight; - } - return new ViewHolder(icon); - case VIEW_TYPE_EMPTY_SEARCH: - return new ViewHolder(mLayoutInflater.inflate(R.layout.all_apps_empty_search, - parent, false)); - case VIEW_TYPE_SEARCH_MARKET: - View searchMarketView = mLayoutInflater.inflate(R.layout.all_apps_search_market, - parent, false); - searchMarketView.setOnClickListener(mMarketSearchClickListener); - return new ViewHolder(searchMarketView); - case VIEW_TYPE_ALL_APPS_DIVIDER: - return new ViewHolder(mLayoutInflater.inflate( - R.layout.all_apps_divider, parent, false)); - default: - BaseAdapterProvider adapterProvider = getAdapterProvider(viewType); - if (adapterProvider != null) { - return adapterProvider.onCreateViewHolder(mLayoutInflater, parent, viewType); - } - throw new RuntimeException("Unexpected view type" + viewType); - } - } - - @Override - public void onBindViewHolder(ViewHolder holder, int position) { - switch (holder.getItemViewType()) { - case VIEW_TYPE_ICON: - AdapterItem adapterItem = mApps.getAdapterItems().get(position); - BubbleTextView icon = (BubbleTextView) holder.itemView; - icon.reset(); - if (adapterItem.itemInfo instanceof AppInfo) { - icon.applyFromApplicationInfo((AppInfo) adapterItem.itemInfo); - } else { - icon.applyFromItemInfoWithIcon(adapterItem.itemInfo); - } - break; - case VIEW_TYPE_EMPTY_SEARCH: - TextView emptyViewText = (TextView) holder.itemView; - emptyViewText.setText(mEmptySearchMessage); - emptyViewText.setGravity(mApps.hasNoFilteredResults() ? Gravity.CENTER : - Gravity.START | Gravity.CENTER_VERTICAL); - break; - case VIEW_TYPE_SEARCH_MARKET: - TextView searchView = (TextView) holder.itemView; - if (mMarketSearchClickListener != null) { - searchView.setVisibility(View.VISIBLE); - } else { - searchView.setVisibility(View.GONE); - } - break; - case VIEW_TYPE_ALL_APPS_DIVIDER: - // nothing to do - break; - default: - BaseAdapterProvider adapterProvider = getAdapterProvider(holder.getItemViewType()); - if (adapterProvider != null) { - adapterProvider.onBindView(holder, position); - } - } - } - - @Override - public void onViewRecycled(@NonNull ViewHolder holder) { - super.onViewRecycled(holder); - } - - @Override - public boolean onFailedToRecycleView(ViewHolder holder) { - // Always recycle and we will reset the view when it is bound - return true; - } - - @Override - public int getItemCount() { - return mApps.getAdapterItems().size(); - } - - @Override - public int getItemViewType(int position) { - AdapterItem item = mApps.getAdapterItems().get(position); - return item.viewType; - } - - protected static boolean isViewType(int viewType, int viewTypeMask) { - return (viewType & viewTypeMask) != 0; - } - - @Nullable - protected BaseAdapterProvider getAdapterProvider(int viewType) { - return Arrays.stream(mAdapterProviders).filter( - adapterProvider -> adapterProvider.isViewSupported(viewType)).findFirst().orElse( - null); - } -} diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java index f542d8eff8..bfc75153a5 100644 --- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java @@ -44,6 +44,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.core.graphics.ColorUtils; +import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.android.launcher3.DeviceProfile; @@ -696,21 +697,18 @@ public abstract class BaseAllAppsContainerView mAppsList, - BaseAdapterProvider[] adapterProviders); - protected int getHeaderBottom() { return (int) getTranslationY(); } - /** Holds a {@link BaseAllAppsAdapter} and related fields. */ + /** Holds a {@link AllAppsGridAdapter} 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; + public final AllAppsGridAdapter adapter; + final LinearLayoutManager mLayoutManager; final AlphabeticalAppsList mAppsList; final Rect mPadding = new Rect(); AllAppsRecyclerView mRecyclerView; @@ -726,7 +724,8 @@ public abstract class BaseAllAppsContainerView(mActivityContext, getLayoutInflater(), mAppsList, + adapterProviders); mAppsList.setAdapter(adapter); mLayoutManager = adapter.getLayoutManager(); } diff --git a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java index fd8945a0f6..0137e2a2c0 100644 --- a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java +++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java @@ -33,7 +33,7 @@ import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.ExtendedEditText; import com.android.launcher3.Launcher; import com.android.launcher3.Utilities; -import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem; +import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.search.SearchAlgorithm; import com.android.launcher3.search.SearchCallback; diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java index cb459eacb3..4a886a457f 100644 --- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java +++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java @@ -38,9 +38,9 @@ import com.android.launcher3.ExtendedEditText; import com.android.launcher3.Insettable; import com.android.launcher3.R; import com.android.launcher3.allapps.ActivityAllAppsContainerView; +import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem; import com.android.launcher3.allapps.AllAppsStore; import com.android.launcher3.allapps.AlphabeticalAppsList; -import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem; import com.android.launcher3.allapps.SearchUiManager; import com.android.launcher3.search.SearchCallback; diff --git a/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java b/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java index 222c8fea47..1f854c6787 100644 --- a/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java +++ b/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java @@ -23,7 +23,7 @@ import android.os.Handler; import androidx.annotation.AnyThread; import com.android.launcher3.LauncherAppState; -import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem; +import com.android.launcher3.allapps.AllAppsGridAdapter.AdapterItem; import com.android.launcher3.model.AllAppsList; import com.android.launcher3.model.BaseModelUpdateTask; import com.android.launcher3.model.BgDataModel;