From 448d718e6abffe21d755d376fef0b9195a9a7d30 Mon Sep 17 00:00:00 2001 From: John Andrew Camu Date: Wed, 15 Jan 2025 13:01:51 +0800 Subject: [PATCH] feat : Initial implementation Caddy (#5166) - Introduced "Caddy" functionality to organize apps within the app drawer. - Allows grouping of applications for better accessibility and user experience. - Serves as a foundational feature for enhancing app drawer usability. --- .../layout/all_apps_folder_application.xml | 23 +++ lawnchair/res/layout/all_apps_folder_icon.xml | 36 ++++ lawnchair/res/values/strings.xml | 4 + .../allapps/LawnchairAlphabeticalAppsList.kt | 43 +++- .../preferences/PreferenceManager.kt | 2 + .../destinations/AppDrawerPreferences.kt | 1 + .../destinations/AppDrawerSettings.kt | 186 ++++++++++++++++++ lawnchair/src/app/lawnchair/util/AppsList.kt | 21 ++ res/values/attrs.xml | 1 + src/com/android/launcher3/BubbleTextView.java | 4 +- .../allapps/AlphabeticalAppsList.java | 4 +- .../launcher3/allapps/BaseAllAppsAdapter.java | 32 ++- src/com/android/launcher3/folder/Folder.java | 10 +- .../android/launcher3/folder/FolderIcon.java | 15 +- .../launcher3/folder/FolderPagedView.java | 11 +- .../launcher3/folder/PreviewItemManager.java | 6 + 16 files changed, 383 insertions(+), 16 deletions(-) create mode 100644 lawnchair/res/layout/all_apps_folder_application.xml create mode 100644 lawnchair/res/layout/all_apps_folder_icon.xml create mode 100644 lawnchair/src/app/lawnchair/ui/preferences/destinations/AppDrawerSettings.kt diff --git a/lawnchair/res/layout/all_apps_folder_application.xml b/lawnchair/res/layout/all_apps_folder_application.xml new file mode 100644 index 0000000000..8e02012883 --- /dev/null +++ b/lawnchair/res/layout/all_apps_folder_application.xml @@ -0,0 +1,23 @@ + + + diff --git a/lawnchair/res/layout/all_apps_folder_icon.xml b/lawnchair/res/layout/all_apps_folder_icon.xml new file mode 100644 index 0000000000..47fb1415af --- /dev/null +++ b/lawnchair/res/layout/all_apps_folder_icon.xml @@ -0,0 +1,36 @@ + + + + + diff --git a/lawnchair/res/values/strings.xml b/lawnchair/res/values/strings.xml index ec328e3f9a..abcedb5c28 100644 --- a/lawnchair/res/values/strings.xml +++ b/lawnchair/res/values/strings.xml @@ -59,6 +59,7 @@ General "words" used throughout Lawnchair --> + Others Dynamic @@ -90,6 +91,9 @@ Wallpapers + Caddy (Beta) + Caddy + To lock your phone when performing a gesture, and to open Recents via gesture, Lawnchair requires accessibility access.\n\nLawnchair doesn\'t watch any user action, though the privilege to do so is required for all accessibility services. Lawnchair discards any event sent by the system.\n\nIn order to lock your phone, or to open Recents, Lawnchair uses the performGlobalAction Accessibility service. diff --git a/lawnchair/src/app/lawnchair/allapps/LawnchairAlphabeticalAppsList.kt b/lawnchair/src/app/lawnchair/allapps/LawnchairAlphabeticalAppsList.kt index e9ccdd6f5f..1b50bf1756 100644 --- a/lawnchair/src/app/lawnchair/allapps/LawnchairAlphabeticalAppsList.kt +++ b/lawnchair/src/app/lawnchair/allapps/LawnchairAlphabeticalAppsList.kt @@ -4,19 +4,23 @@ import android.content.Context import android.util.Log import androidx.lifecycle.lifecycleScope import app.lawnchair.launcher +import app.lawnchair.preferences.PreferenceManager import app.lawnchair.preferences2.PreferenceManager2 +import app.lawnchair.util.categorizeApps import com.android.launcher3.allapps.AllAppsStore import com.android.launcher3.allapps.AlphabeticalAppsList +import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem import com.android.launcher3.allapps.PrivateProfileManager import com.android.launcher3.allapps.WorkProfileManager import com.android.launcher3.model.data.AppInfo +import com.android.launcher3.model.data.FolderInfo import com.android.launcher3.model.data.ItemInfo import com.android.launcher3.views.ActivityContext import com.patrykmichalik.opto.core.onEach import java.util.function.Predicate class LawnchairAlphabeticalAppsList( - context: T, + private val context: T, appsStore: AllAppsStore, workProfileManager: WorkProfileManager?, privateProfileManager: PrivateProfileManager?, @@ -24,11 +28,11 @@ class LawnchairAlphabeticalAppsList( where T : Context, T : ActivityContext { private var hiddenApps: Set = setOf() - private val prefs = PreferenceManager2.getInstance(context) - + private val prefs2 = PreferenceManager2.getInstance(context) + private val prefs = PreferenceManager.getInstance(context) init { try { - prefs.hiddenApps.onEach(launchIn = context.launcher.lifecycleScope) { + prefs2.hiddenApps.onEach(launchIn = context.launcher.lifecycleScope) { hiddenApps = it onAppsUpdated() } @@ -45,4 +49,35 @@ class LawnchairAlphabeticalAppsList( } onAppsUpdated() } + + override fun addAppsWithSections(appList: List?, startPosition: Int): Int { + if (appList.isNullOrEmpty()) return startPosition + val drawerListDefault = prefs.drawerList.get() + var position = startPosition + + if (!drawerListDefault) { + val categorizedApps = categorizeApps(context, appList) + + if (categorizedApps.isNotEmpty()) { + for ((category, apps) in categorizedApps) { + if (apps.size <= 1) { + val app = apps[0] + mAdapterItems.add(AdapterItem.asApp(app)) + } else { + val folderInfo = FolderInfo() + folderInfo.title = category + for (app in apps) { + folderInfo.add(app) + } + mAdapterItems.add(AdapterItem.asFolder(folderInfo)) + } + position++ + } + } + } else { + position = super.addAppsWithSections(appList, startPosition) + } + + return position + } } diff --git a/lawnchair/src/app/lawnchair/preferences/PreferenceManager.kt b/lawnchair/src/app/lawnchair/preferences/PreferenceManager.kt index 1d90488d91..e791d59cac 100644 --- a/lawnchair/src/app/lawnchair/preferences/PreferenceManager.kt +++ b/lawnchair/src/app/lawnchair/preferences/PreferenceManager.kt @@ -115,6 +115,8 @@ class PreferenceManager private constructor(private val context: Context) : val wallpaperBlur = IntPref("pref_wallpaperBlur", 25, recreate) val wallpaperBlurFactorThreshold = FloatPref("pref_wallpaperBlurFactor", 3.0F, recreate) + val drawerList = BoolPref("pref_drawerList", true, recreate) + val recentsActionScreenshot = BoolPref("pref_recentsActionScreenshot", !isOnePlusStock) val recentsActionShare = BoolPref("pref_recentsActionShare", isOnePlusStock) val recentsActionLens = BoolPref("pref_recentsActionLens", true) diff --git a/lawnchair/src/app/lawnchair/ui/preferences/destinations/AppDrawerPreferences.kt b/lawnchair/src/app/lawnchair/ui/preferences/destinations/AppDrawerPreferences.kt index c91684dfc3..795adeef01 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/destinations/AppDrawerPreferences.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/destinations/AppDrawerPreferences.kt @@ -53,6 +53,7 @@ fun AppDrawerPreferences( backArrowVisible = !LocalIsExpandedScreen.current, modifier = modifier, ) { + AppDrawerSettings() PreferenceGroup(heading = stringResource(id = R.string.general_label)) { ColorPreference(preference = prefs2.appDrawerBackgroundColor) SliderPreference( diff --git a/lawnchair/src/app/lawnchair/ui/preferences/destinations/AppDrawerSettings.kt b/lawnchair/src/app/lawnchair/ui/preferences/destinations/AppDrawerSettings.kt new file mode 100644 index 0000000000..717657ddcc --- /dev/null +++ b/lawnchair/src/app/lawnchair/ui/preferences/destinations/AppDrawerSettings.kt @@ -0,0 +1,186 @@ +package app.lawnchair.ui.preferences.destinations + +import androidx.compose.animation.animateColorAsState +import androidx.compose.animation.core.tween +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import app.lawnchair.preferences.preferenceManager +import com.android.launcher3.R + +@Composable +fun AppDrawerSettings( + modifier: Modifier = Modifier, +) { + val prefs = preferenceManager() + val context = LocalContext.current + val resources = context.resources + var selectedOption by remember { mutableStateOf(prefs.drawerList.get()) } + + Row( + modifier = modifier + .fillMaxWidth() + .background(MaterialTheme.colorScheme.background) + .padding(16.dp), + horizontalArrangement = Arrangement.SpaceBetween, + ) { + ButtonSection( + modifier = Modifier, + label = resources.getString(R.string.feed_default), + isSelected = selectedOption, + onClick = { + selectedOption = true + prefs.drawerList.set(true) + }, + gridLayout = { + Column(modifier = Modifier, horizontalAlignment = Alignment.CenterHorizontally) { + Row( + modifier = Modifier, + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + repeat(4) { + Box( + modifier = Modifier + .size(16.dp) + .background( + MaterialTheme.colorScheme.surfaceVariant, + CircleShape, + ), + ) + } + } + } + }, + ) + + Spacer(modifier = Modifier.width(16.dp)) + + ButtonSection( + modifier = Modifier, + label = resources.getString(R.string.caddy_beta), + isSelected = !selectedOption, + onClick = { + selectedOption = false + prefs.drawerList.set(false) + }, + gridLayout = { + Column(modifier = Modifier, horizontalAlignment = Alignment.CenterHorizontally) { + Row( + modifier = Modifier, + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + repeat(2) { + Box( + modifier = Modifier + .size(16.dp) + .background( + MaterialTheme.colorScheme.surfaceVariant, + CircleShape, + ), + ) + } + } + Spacer(modifier = Modifier.height(8.dp)) + Row( + modifier = Modifier, + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + repeat(2) { + Box( + modifier = Modifier + .size(16.dp) + .background( + MaterialTheme.colorScheme.surfaceVariant, + CircleShape, + ), + ) + } + } + } + }, + ) + } +} + +@Composable +fun ButtonSection( + label: String, + isSelected: Boolean, + onClick: () -> Unit, + modifier: Modifier = Modifier, + gridLayout: @Composable () -> Unit, +) { + val backgroundColor by animateColorAsState( + targetValue = if (isSelected) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.surfaceContainer, + animationSpec = tween(durationMillis = 300), + ) + + val textColor by animateColorAsState( + targetValue = if (isSelected) MaterialTheme.colorScheme.onPrimary else MaterialTheme.colorScheme.onSurface, + animationSpec = tween(durationMillis = 300), + ) + + Box( + modifier = modifier + .size(160.dp, 120.dp) + .background(backgroundColor, RoundedCornerShape(16.dp)) + .clickable { onClick() } + .padding(12.dp), + ) { + Column( + modifier = Modifier.fillMaxSize(), + verticalArrangement = Arrangement.SpaceBetween, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Box( + modifier = Modifier + .height(24.dp) + .fillMaxWidth(0.8f) + .background(MaterialTheme.colorScheme.surfaceVariant, RoundedCornerShape(8.dp)), + ) + + gridLayout() + + Text( + modifier = Modifier, + text = label, + color = textColor, + fontSize = 14.sp, + ) + } + } +} + +@Preview(showBackground = true) +@Composable +private fun PreviewToggleSelectionUI() { + Surface { + AppDrawerSettings() + } +} diff --git a/lawnchair/src/app/lawnchair/util/AppsList.kt b/lawnchair/src/app/lawnchair/util/AppsList.kt index dca4b0c945..2bc123a96f 100644 --- a/lawnchair/src/app/lawnchair/util/AppsList.kt +++ b/lawnchair/src/app/lawnchair/util/AppsList.kt @@ -17,6 +17,7 @@ package app.lawnchair.util import android.content.Context +import android.content.pm.ApplicationInfo import android.content.pm.LauncherActivityInfo import android.content.pm.LauncherApps import android.graphics.Bitmap @@ -29,6 +30,7 @@ import androidx.compose.runtime.remember import androidx.compose.ui.platform.LocalContext import com.android.launcher3.AppFilter import com.android.launcher3.LauncherAppState +import com.android.launcher3.R import com.android.launcher3.Utilities import com.android.launcher3.model.data.AppInfo import com.android.launcher3.pm.UserCache @@ -76,3 +78,22 @@ class App(context: Context, private val info: LauncherActivityInfo) { } val appComparator: Comparator = comparing { it.label.lowercase(Locale.getDefault()) } +val packageInfoCache = mutableMapOf() + +fun categorizeApps(context: Context, appList: List?): Map> { + val categories = mutableMapOf>() + val validAppList = appList?.filterNotNull() ?: emptyList() + for (appInfo in validAppList) { + val packageName = appInfo.targetPackage!! + val applicationInfo = packageInfoCache.getOrPut(packageName) { + context.packageManager.getApplicationInfo(packageName, 0) + } + val categoryTitle = ApplicationInfo.getCategoryTitle(context, applicationInfo.category) ?: context.resources.getString(R.string.others_category_label) + val categoryList = categories.getOrPut(categoryTitle.toString()) { mutableListOf() } + if (!categoryList.contains(appInfo)) { + categoryList.add(appInfo) + } + } + + return categories.toSortedMap().mapValues { it.value } +} diff --git a/res/values/attrs.xml b/res/values/attrs.xml index be8b2e13d9..c46b7c7e3e 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -94,6 +94,7 @@ + diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index a6dc0da54a..e081442067 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -116,6 +116,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, public static final int DISPLAY_PREDICTION_ROW = 8; public static final int DISPLAY_SEARCH_RESULT_APP_ROW = 9; + private static final int DISPLAY_DRAWER_FOLDER = 10; + private static final float MIN_LETTER_SPACING = -0.05f; private static final int MAX_SEARCH_LOOP_COUNT = 20; private static final Character NEW_LINE = '\n'; @@ -250,7 +252,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, defaultIconSize = mDeviceProfile.iconSizePx; setCenterVertically(mDeviceProfile.iconCenterVertically); } else if (mDisplay == DISPLAY_ALL_APPS || mDisplay == DISPLAY_PREDICTION_ROW - || mDisplay == DISPLAY_SEARCH_RESULT_APP_ROW) { + || mDisplay == DISPLAY_SEARCH_RESULT_APP_ROW || mDisplay == DISPLAY_DRAWER_FOLDER) { setTextSize(TypedValue.COMPLEX_UNIT_PX, mDeviceProfile.allAppsIconTextSizePx); setCompoundDrawablePadding(mDeviceProfile.allAppsIconDrawablePaddingPx); defaultIconSize = mDeviceProfile.allAppsIconSizePx; diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java index 4b2b5a861f..1c4acf8fc0 100644 --- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java +++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java @@ -92,7 +92,7 @@ public class AlphabeticalAppsList implement // The number of results in current adapter private int mAccessibilityResultsCount = 0; // The current set of adapter items - private final ArrayList mAdapterItems = new ArrayList<>(); + protected final ArrayList mAdapterItems = new ArrayList<>(); // The set of sections that we allow fast-scrolling to (includes non-merged // sections) private final List mFastScrollerSections = new ArrayList<>(); @@ -399,7 +399,7 @@ public class AlphabeticalAppsList implement return position; } - private int addAppsWithSections(List appList, int startPosition) { + protected int addAppsWithSections(List appList, int startPosition) { String lastSectionName = null; boolean hasPrivateApps = false; int position = startPosition; diff --git a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java index a5c54b41ad..c3af72bae6 100644 --- a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java +++ b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java @@ -32,6 +32,7 @@ import android.view.View.OnClickListener; import android.view.View.OnFocusChangeListener; import android.view.View.OnLongClickListener; import android.view.ViewGroup; +import android.widget.FrameLayout; import android.widget.RelativeLayout; import android.widget.TextView; @@ -44,7 +45,9 @@ import com.android.launcher3.LauncherPrefs; import com.android.launcher3.R; import com.android.launcher3.allapps.search.SearchAdapterProvider; import com.android.launcher3.config.FeatureFlags; +import com.android.launcher3.folder.FolderIcon; import com.android.launcher3.model.data.AppInfo; +import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.util.Themes; import com.android.launcher3.views.ActivityContext; @@ -74,11 +77,13 @@ public abstract class BaseAllAppsAdapter ex public static final int VIEW_TYPE_PRIVATE_SPACE_SYS_APPS_DIVIDER = 1 << 7; public static final int VIEW_TYPE_WORK_EDU_CARD = 1 << 8; - public static final int NEXT_ID = 8; + public static final int VIEW_TYPE_FOLDER = 1 << 9; + + public static final int NEXT_ID = 10; // 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; + public static final int VIEW_TYPE_MASK_ICON = VIEW_TYPE_ICON | VIEW_TYPE_FOLDER; public static final int VIEW_TYPE_MASK_PRIVATE_SPACE_HEADER = VIEW_TYPE_PRIVATE_SPACE_HEADER; public static final int VIEW_TYPE_MASK_PRIVATE_SPACE_SYS_APPS_DIVIDER = VIEW_TYPE_PRIVATE_SPACE_SYS_APPS_DIVIDER; @@ -115,6 +120,8 @@ public abstract class BaseAllAppsAdapter ex public int rowAppIndex; // The associated ItemInfoWithIcon for the item public AppInfo itemInfo = new AppInfo(); + + public FolderInfo folderInfo = new FolderInfo(); // Private App Decorator public SectionDecorationInfo decorationInfo = null; @@ -131,6 +138,12 @@ public abstract class BaseAllAppsAdapter ex item.itemInfo = appInfo; return item; } + + public static AdapterItem asFolder(FolderInfo folderInfo) { + AdapterItem item = new AdapterItem(VIEW_TYPE_FOLDER); + item.folderInfo = folderInfo; + return item; + } public static AdapterItem asAppWithDecorationInfo(AppInfo appInfo, SectionDecorationInfo decorationInfo) { @@ -140,7 +153,7 @@ public abstract class BaseAllAppsAdapter ex } protected boolean isCountedForAccessibility() { - return viewType == VIEW_TYPE_ICON; + return viewType == VIEW_TYPE_ICON || viewType == VIEW_TYPE_FOLDER; } /** @@ -257,6 +270,12 @@ public abstract class BaseAllAppsAdapter ex case VIEW_TYPE_PRIVATE_SPACE_HEADER: return new ViewHolder(mLayoutInflater.inflate( R.layout.private_space_header, parent, false)); + case VIEW_TYPE_FOLDER: + FrameLayout fl = new FrameLayout(mActivityContext); + ViewGroup.MarginLayoutParams lp = new ViewGroup.MarginLayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT); + return new ViewHolder(fl); default: if (mAdapterProvider.isViewSupported(viewType)) { return mAdapterProvider.onCreateViewHolder(mLayoutInflater, parent, viewType); @@ -333,6 +352,13 @@ public abstract class BaseAllAppsAdapter ex case VIEW_TYPE_WORK_EDU_CARD: ((WorkEduCard) holder.itemView).setPosition(position); break; + case VIEW_TYPE_FOLDER: + FolderInfo folderInfo = mApps.getAdapterItems().get(position).folderInfo; + ViewGroup container = (ViewGroup) holder.itemView; + container.removeAllViews(); + container.addView(FolderIcon.inflateFolderAndIcon(R.layout.all_apps_folder_icon, mActivityContext, + container, folderInfo)); + break; default: if (mAdapterProvider.isViewSupported(holder.getItemViewType())) { mAdapterProvider.onBindView(holder, position); diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java index 7495cdbcfb..2a37ea66dc 100644 --- a/src/com/android/launcher3/folder/Folder.java +++ b/src/com/android/launcher3/folder/Folder.java @@ -403,6 +403,8 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo if (dragObject.dragSource != this) { return; } + if (isInAppDrawer()) close(true); + mContent.removeItem(mCurrentDragView); mItemsInvalidated = true; @@ -415,6 +417,10 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo mItemAddedBackToSelfViaIcon = false; } + public boolean isInAppDrawer() { + return mInfo.container == ItemInfo.NO_ID; + } + @Override public void onDragEnd() { if (mIsExternalDrag && mIsDragInProgress) { @@ -583,7 +589,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo } // In case any children didn't come across during loading, clean up the folder accordingly mFolderIcon.post(() -> { - if (getItemCount() <= 1) { + if (getItemCount() <= 1 && !isInAppDrawer()) { replaceFolderWithFinalItem(); } }); @@ -971,7 +977,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo mRearrangeOnClose = false; } if (getItemCount() <= 1) { - if (!mIsDragInProgress && !mSuppressFolderDeletion) { + if (!mIsDragInProgress && !mSuppressFolderDeletion && !isInAppDrawer()) { replaceFolderWithFinalItem(); } else if (mIsDragInProgress) { mDeleteFolderOnDropCompleted = true; diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java index 4c2180cecd..cc5395b7c2 100644 --- a/src/com/android/launcher3/folder/FolderIcon.java +++ b/src/com/android/launcher3/folder/FolderIcon.java @@ -207,7 +207,12 @@ public class FolderIcon extends FrameLayout implements FolderListener, FloatingI icon.mFolderName.setText(folderInfo.title); icon.mFolderName.setCompoundDrawablePadding(0); FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) icon.mFolderName.getLayoutParams(); - lp.topMargin = grid.iconSizePx + grid.iconDrawablePaddingPx; + if (folderInfo.container == ItemInfo.NO_ID) { + lp.topMargin = grid.allAppsIconSizePx + grid.allAppsIconDrawablePaddingPx; + icon.mBackground = new PreviewBackground(activity.getDragLayer().getContext()); + } else { + lp.topMargin = grid.iconSizePx + grid.iconDrawablePaddingPx; + } icon.setTag(folderInfo); icon.setOnClickListener(activity.getItemOnClickListener()); @@ -344,7 +349,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, FloatingI final Launcher launcher = (Launcher) mActivity; DragLayer dragLayer = launcher.getDragLayer(); Rect to = finalRect; - if (to == null) { + if (to == null && !isInAppDrawer()) { to = new Rect(); Workspace workspace = launcher.getWorkspace(); // Set cellLayout and this to it's final state to compute final animation locations @@ -434,6 +439,10 @@ public class FolderIcon extends FrameLayout implements FolderListener, FloatingI addItem(item); } } + + public boolean isInAppDrawer() { + return mInfo.container == ItemInfo.NO_ID; + } /** * Set the suggested folder name. @@ -772,12 +781,14 @@ public class FolderIcon extends FrameLayout implements FolderListener, FloatingI } public void clearLeaveBehindIfExists() { + if (isInAppDrawer()) return; if (getParent() instanceof FolderIconParent) { ((FolderIconParent) getParent()).clearFolderLeaveBehind(this); } } public void drawLeaveBehindIfExists() { + if (isInAppDrawer()) return; if (getParent() instanceof FolderIconParent) { ((FolderIconParent) getParent()).drawFolderLeaveBehindForIcon(this); } diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java index 6baba99f56..221613312d 100644 --- a/src/com/android/launcher3/folder/FolderPagedView.java +++ b/src/com/android/launcher3/folder/FolderPagedView.java @@ -37,6 +37,7 @@ import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BubbleTextView; import com.android.launcher3.CellLayout; import com.android.launcher3.DeviceProfile; +import com.android.launcher3.Item; import com.android.launcher3.PagedView; import com.android.launcher3.R; import com.android.launcher3.ShortcutAndWidgetContainer; @@ -46,6 +47,7 @@ import com.android.launcher3.celllayout.CellLayoutLayoutParams; import com.android.launcher3.keyboard.ViewGroupFocusHelper; import com.android.launcher3.model.data.AppPairInfo; import com.android.launcher3.model.data.ItemInfo; +import com.android.launcher3.model.data.ItemInfoWithIcon; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.pageindicators.PageIndicatorDots; import com.android.launcher3.util.LauncherBindableItemsContainer.ItemOperator; @@ -225,8 +227,13 @@ public class FolderPagedView extends PagedView implements Cli icon = AppPairIcon.inflateIcon(R.layout.folder_app_pair, ActivityContext.lookupContext( getContext()), null , api, BubbleTextView.DISPLAY_FOLDER); } else { - icon = mViewCache.getView(R.layout.folder_application, getContext(), null); - ((BubbleTextView) icon).applyFromWorkspaceItem((WorkspaceItemInfo) item); + if (mFolder.isInAppDrawer()) { + icon = mViewCache.getView(R.layout.all_apps_folder_application, getContext(), null); + ((BubbleTextView) icon).applyFromItemInfoWithIcon((ItemInfoWithIcon) item); + } else { + icon = mViewCache.getView(R.layout.folder_application, getContext(), null); + ((BubbleTextView) icon).applyFromWorkspaceItem((WorkspaceItemInfo) item); + } } icon.setOnClickListener(mFolder.mActivityContext.getItemOnClickListener()); diff --git a/src/com/android/launcher3/folder/PreviewItemManager.java b/src/com/android/launcher3/folder/PreviewItemManager.java index ac0fb5be2f..cbb4d4ea7a 100644 --- a/src/com/android/launcher3/folder/PreviewItemManager.java +++ b/src/com/android/launcher3/folder/PreviewItemManager.java @@ -35,6 +35,7 @@ import android.graphics.PointF; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.util.FloatProperty; +import android.util.Log; import android.view.View; import androidx.annotation.NonNull; @@ -47,6 +48,7 @@ import com.android.launcher3.apppairs.AppPairIconDrawingParams; import com.android.launcher3.apppairs.AppPairIconGraphic; import com.android.launcher3.graphics.PreloadIconDrawable; import com.android.launcher3.model.data.AppPairInfo; +import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.ItemInfoWithIcon; import com.android.launcher3.model.data.WorkspaceItemInfo; @@ -463,6 +465,10 @@ public class PreviewItemManager { AppPairIconDrawingParams appPairParams = new AppPairIconDrawingParams(mContext, DISPLAY_FOLDER); p.drawable = AppPairIconGraphic.composeDrawable(api, appPairParams); p.drawable.setBounds(0, 0, mIconSize, mIconSize); + } else if (item instanceof ItemInfoWithIcon withIcon){ + p.drawable = withIcon.newIcon(mContext, + Themes.isThemedIconEnabled(mContext) ? FLAG_THEMED : 0); + p.drawable.setBounds(0, 0, mIconSize, mIconSize); } p.item = item;