Esta guía detalla cómo modificar Launcher3 en Android 11 para eliminar la vista de cajón (All App Drawer) y mostrar todos los iconos de aplicaciones directamente en el escritorio — sin necesidad de acceder a un menú separado. A diferencia de Android 12, donde los cambios suelen centrarse en AllAppsContainerView y controladores de transición, en Android 11 la arquitectura requiere ajustes más profundos en el flujo de carga, disposición y manejo de eventos táctiles.
Clases clave involucradas
Los siguientes componentes deben adaptarse para desactivar el cajón y redistribuir los íconos como elementos nativos del workspace:
AllAppsTransitionController: gestiona la transición entre estados visuaelsFeatureFlags: habilita/deshabilita funcionalidades mediante constantes estáticasLoaderTaskyLoaderCursor: orquestan la carga y validación de íconosAddWorkspaceItemsTask: determina qué íconos se insertan en el escritorioDragControlleryDeleteDropTarget: controlan interacciones táctiles y eliminaciónDeviceProfileyInvariantDeviceProfile: definen el layout y densidad de cuadrículaHotseatyAbstractStateChangeTouchController: gestionan la barra inferior y el comportamiento táctil global
Implementación paso a paso
1. Habilitar el modo sin cajón mediante FeatureFlags
En packages/apps/Launcher3/src/com/android/launcher3/config/FeatureFlags.java, añada:
public static final boolean SHOW_ALL_APPS_IN_WORKSPACE = true;
2. Ocultar la capa de sombra del cajón
En AllAppsTransitionController.java, modifique setupViews():
public void setupViews(AllAppsContainerView appsView, ScrimView scrimView) {
mAppsView = appsView;
mScrimView = scrimView;
if (SHOW_ALL_APPS_IN_WORKSPACE) {
mScrimView.setVisibility(View.GONE);
}
// ... resto del código
}
3. Redirigir la carga de aplicaciones al workspace
En LoaderTask.java, sustituya la llamada a mResults.bindAllApps() por una inserción directa:
if (SHOW_ALL_APPS_IN_WORKSPACE) {
bindAllAppsToDesktop();
} else {
mResults.bindAllApps();
}
Y defina bindAllAppsToDesktop() así:
private void bindAllAppsToDesktop() {
List<AppInfo> sortedApps = new ArrayList<>(mBgAllAppsList.data);
sortedApps.sort((a, b) -> a.title.toString().compareToIgnoreCase(b.title.toString()));
List<Pair<ItemInfo, Object>> queue = new ArrayList<>();
for (AppInfo app : sortedApps) {
queue.add(Pair.create(app.makeWorkspaceItem(), null));
}
mApp.getModel().addAndBindAddedWorkspaceItems(queue);
}
4. Deshabilitar restricciones de ubicación para íconos
En LoaderCursor.java, evite que checkItemPlacement() rechace íconos destinados al escritorio:
protected boolean checkItemPlacement(ItemInfo item) {
if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT &&
SHOW_ALL_APPS_IN_WORKSPACE) {
return false; // Ignorar hotseat si está desactivado
}
// ... lógica original restante
}
5. Ajustar la cuadrícula del escritorio
En InvariantDeviceProfile.java, sobrescriba las dimensiones de la grilla cuando esté activo el modo sin cajón:
if (SHOW_ALL_APPS_IN_WORKSPACE) {
numRows = 6;
numColumns = 5;
numHotseatIcons = 0;
}
6. Suprimir interacciones innecesarias
En AbstractStateChangeTouchController.java, bloquee la interceptación táctil para evitar gestos asociados al cajón:
@Override
public final boolean onControllerInterceptTouchEvent(MotionEvent ev) {
if (SHOW_ALL_APPS_IN_WORKSPACE) {
return false;
}
// ... lógica original
}
7. Reconfigurar la barra inferior (hotseat)
En Hotseat.java, oculte visualmente la barra cuando no se usa:
@Override
public void setInsets(Rect insets) {
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
DeviceProfile grid = mActivity.getDeviceProfile();
if (SHOW_ALL_APPS_IN_WORKSPACE) {
lp.height = 0;
setVisibility(View.GONE);
} else {
// ... lógica original
}
setLayoutParams(lp);
}
8. Evitar duplicados durante actualizaciones de paquetes
En PackageUpdatedTask.java, invoque la reinserción tras cada cambio:
if (SHOW_ALL_APPS_IN_WORKSPACE) {
bindAllAppsToDesktop(app, mBgAllAppsList);
}
Consideraciones adicionales
Al implementar este cambio, es fundamental:
- Asegurarse de que
AddWorkspaceItemsTaskno filtre aplicaciones del sistema — elimine las comprobaciones dePackageManagerHelper.isSystemApp()bajo la condiciónSHOW_ALL_APPS_IN_WORKSPACE. - Desactivar la lógica de
hotseatBarSizePxenDeviceProfile.javapara evitar márgenes residuales. - Validar que
DeleteDropTarget.canRemove()retornefalsepara íconos de aplicación cuando el modo está activo, evitando eliminaciones accidentales. - Recompilar con
m launchery limpiar cachés previos (make clobber) para evitar inconsistencias.
Este enfoque transforma Launcher3 en un entorno de escritorio plano y altamente personalizable, ideal para dispositivos especializados o interfaces minimalsitas.