Personalizar Launcher3 en Android 11 para mostrar todas las aplicaciones directamente en el escritorio

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 visuaels
  • FeatureFlags: habilita/deshabilita funcionalidades mediante constantes estáticas
  • LoaderTask y LoaderCursor: orquestan la carga y validación de íconos
  • AddWorkspaceItemsTask: determina qué íconos se insertan en el escritorio
  • DragController y DeleteDropTarget: controlan interacciones táctiles y eliminación
  • DeviceProfile y InvariantDeviceProfile: definen el layout y densidad de cuadrícula
  • Hotseat y AbstractStateChangeTouchController: 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 AddWorkspaceItemsTask no filtre aplicaciones del sistema — elimine las comprobaciones de PackageManagerHelper.isSystemApp() bajo la condición SHOW_ALL_APPS_IN_WORKSPACE.
  • Desactivar la lógica de hotseatBarSizePx en DeviceProfile.java para evitar márgenes residuales.
  • Validar que DeleteDropTarget.canRemove() retorne false para íconos de aplicación cuando el modo está activo, evitando eliminaciones accidentales.
  • Recompilar con m launcher y 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.

Etiquetas: Android11 Launcher3 custom-rom workspace-layout system-ui

Publicado el 10-5 15:16