Administración de ventanas

ChromeOS admite apps para Android en varias ventanas. El sistema renderiza apps en contenedores de ventana cuyo tamaño se determina por el factor de forma del dispositivo, como se muestra en la figura 1.

Figura 1: Ventana de una app en diferentes dispositivos

Es importante crear diseños que funcionen con diferentes tamaños de pantalla. Si sigues los lineamientos de Android para admitir diferentes tamaños de pantalla, tu app también funcionará bien cuando se ejecute en ChromeOS.

En esta página, se muestra cómo asegurarte de que la ventana de tu app se inicie correctamente, cambie el tamaño de manera fluida y muestre todo su contenido cuando cambie el tamaño.

Tamaño inicial de lanzamiento

Las apps pueden solicitar su tamaño de lanzamiento inicial de las siguientes maneras:

  • Usa un tamaño de lanzamiento solo en entornos de escritorio, lo que ayuda al administrador de ventanas a brindarte los límites y la orientación adecuados. Para indicar una preferencia cuando se usa en modo escritorio, agrega las siguientes metaetiquetas en de la etiqueta <activity>:
<meta-data android:name="WindowManagerPreference:FreeformWindowSize"
           android:value="[phone|tablet|maximize]" />
<meta-data android:name="WindowManagerPreference:FreeformWindowOrientation"
           android:value="[portrait|landscape]" />
  • Usa límites de lanzamiento estáticos. Usa <layout> dentro de la entrada de manifiesto de tu actividad para especificar un tamaño inicial "fijo", como en el siguiente ejemplo:
<layout android:defaultHeight="500dp"
            android:defaultWidth="600dp"
            android:gravity="top|end"
            android:minHeight="450dp"
            android:minWidth="300dp" />
  • Usa límites de lanzamiento dinámicos. Una actividad puede crear y usar el elemento ActivityOptions.setLaunchBounds(Rect) en la creación de una nueva actividad. Cuando especificas un rectángulo vacío, tu app se puede maximizar.

Cambiar el tamaño de las ventanas

En ChromeOS, los usuarios pueden cambiar el tamaño de la ventana de una app de la manera habitual: arrastrando la esquina inferior derecha, como se muestra en la figura 2.

Figura 2: Ventana de una app que puede cambiar de tamaño

Existen dos opciones para controlar el cambio de tamaño de una ventana cuando se usa la clase View:

  • Llama a onConfigurationChanged(..) para responder a los cambios de configuración de forma dinámica. Por ejemplo, puedes agregar android:configChanges="screenSize|smallestScreenSize|orientation|screenLayout" al manifiesto de la actividad. Para obtener más información sobre cómo controlar los cambios de configuración, consulta Cómo controlar los cambios de configuración.
  • Permite que el sistema reinicie la actividad. En este caso, implementa onSaveInstanceState y usa el componente de arquitectura ViewModel para restablecer el estado guardado anteriormente.

Cuando usas Jetpack Compose, el comportamiento de cambio de tamaño depende de la configuración de tu actividad. Si controla los cambios de forma dinámica, se activa una recomposición cuando cambia el tamaño de la ventana. Si el sistema reinicia la actividad, se produce una composición inicial después del reinicio. De cualquier manera, es importante crear diseños de Compose que se adapten a los cambios de tamaño de las ventanas. No supongas que son tamaños fijos.

Dimensiones de una ventana

Haz que tus actividades lean las dimensiones de la ventana cada vez que se inicien y organicen el contenido según la configuración actual.

Para determinar la configuración actual, llama al objeto getResources().getConfiguration() en la actividad actual. No uses la configuración de la actividad en segundo plano ni el recurso del sistema. La actividad en segundo plano no tiene un tamaño, y la configuración del sistema puede contener varias ventanas con tamaños y orientaciones en conflicto, por lo que no se pueden extraer datos que se puedan usar.

Ten en cuenta que el tamaño de la ventana y el tamaño de pantalla no son los mismos. Para obtener el tamaño de la ventana en DP, usa los objetos Activity.getResources().getConfiguration().screenWidth y Activity.getResources().getConfiguration().screenHeight. Es probable que nunca debas usar el tamaño de la pantalla.

Límites del contenido

Los límites del contenido de una ventana pueden cambiar después de cambiar el tamaño. Por ejemplo, el área dentro de la ventana que usa la app puede cambiar si la ventana se agranda demasiado para ajustarse a la pantalla. Por ello, sigue estos lineamientos:

  • Las apps que usan el proceso de diseño de Android se presentan automáticamente en el espacio disponible.
  • Las apps nativas deben leer el área disponible y supervisar los cambios de tamaño para evitar tener elementos de la IU inaccesibles. Llama a los siguientes métodos a fin de determinar el tamaño inicial disponible para esta plataforma:

    • NativeActivity.mLastContent[X/Y/Width/Height]()
    • findViewById(android.R.id.content).get[Width/Height]()

    El monitoreo continuo se puede realizar con un observador:

    • NativeActivity.onContentRectChangedNative()
    • NativeActivity.onGlobalLayout()
    • Agrega un objeto de escucha a view.addOnLayoutChangeListener(findViewById(android.R.id.content))

    Si la app ajusta previamente su material gráfico, hazlo cada vez que cambie la resolución.

Cómo cambiar el tamaño de formato libre

ChromeOS permite cambiar el tamaño de cualquier ventana libremente: el usuario puede cambiar el ancho, la altura y la posición de una ventana en la pantalla. Muchas apps para Android están escritas sin tener en cuenta el cambio de tamaño de formato libre. Considera los siguientes problemas:

  • La posición de la pantalla puede cambiar. Siempre usa el sistema para realizar transformaciones de las coordenadas de ventana a pantalla y de pantalla a ventana.
  • Si usas el sistema de vista de Android, el diseño de la ventana cambia automáticamente cuando cambia su tamaño.
  • Si no usas el sistema de vista y tomas control de la superficie, tu app debe controlar los cambios de tamaño por su cuenta.
  • En el caso de las apps nativas, usa los miembros de mLastContent o la vista de contenido para determinar el tamaño inicial.
  • Cuando se esté ejecutando la app, escucha los eventos onContentRectChangedNative o onGlobalLayout para reaccionar a los cambios de tamaño.
  • Cuando cambie el tamaño de la app, cambia la escala o vuelve a cargar los diseños y el material gráfico, y actualiza las áreas de entrada.

Modo de pantalla completa

El modo de pantalla completa funciona de la misma manera que en Android. Si la ventana no cubre la pantalla completa, se ignoran las solicitudes de uso de pantalla completa (que oculta todos los elementos de la IU del sistema). Cuando se maximiza la app, se realizan los métodos, los diseños y las funciones de pantalla completa habituales, lo que oculta los elementos de la IU del sistema (la barra de control de la ventana y la biblioteca).

Orientación de la pantalla

La orientación más común de una app para Android es la vertical, ya que la mayoría de los teléfonos se sostienen de esa manera. Si bien la orientación vertical es buena para los teléfonos, es mala para las laptops y tablets, en las que se prefiere la orientación horizontal. A fin de obtener los mejores resultados para tu app, procura admitir ambas orientaciones.

Algunas apps para Android suponen que, cuando un dispositivo se mantiene en modo vertical, el valor de rotación es Surface.ROTATION_0. Esto podría ser así para la mayoría de los dispositivos Android. Sin embargo, cuando la app se encuentra en un modo ARC determinado, es posible que el valor de rotación de la orientación vertical no sea Surface.ROTATION_0.

Si deseas obtener un valor de rotación preciso mientras se lee el acelerómetro o sensores similares, usa el método Display.getRotation() para intercambiar el eje según corresponda.

La actividad raíz y la orientación

Una ventana de Chromebook consta de una pila de ventanas de actividad. Cada ventana de la pila tiene el mismo tamaño y la misma orientación.

Los cambios de tamaño y orientación repentinos son confusos en un entorno de escritorio. El administrador de ventanas de la Chromebook evita esto de una manera similar al modo de lado a lado de Android: la actividad de la parte inferior de la pila controla los atributos de todas las actividades superiores. Esto puede dar lugar a situaciones inesperadas en las que una actividad recién iniciada que está en modo vertical y que no se puede cambiar de tamaño se convierte en horizontal y de tamaño variable.

El modo del dispositivo tiene un efecto aquí: en el modo tablet, la orientación no está bloqueada, y cada ventana conserva su propia orientación, como es normal en Android.

Lineamientos de orientación

Sigue estos lineamientos para procesar la orientación:

  • Si solo admites una orientación, agrega la información al manifiesto para que el administrador de ventanas esté al tanto de esto antes de iniciar la aplicación. Cuando especifiques una orientación, asegúrate de proporcionar detalles de las orientaciones de los sensores siempre que sea posible. Las Chromebooks suelen ser convertibles, y una app al revés es una mala experiencia del usuario.
  • Intenta mantener una única orientación seleccionada. Evita solicitar una orientación en el manifiesto y establecer otra orientación programática más tarde.
  • Ten cuidado cuando cambies la orientación según el tamaño de la ventana. Es posible que el usuario se quede atascado en una ventana pequeña de tamaño vertical y no pueda volver a una ventana horizontal más grande.
  • En Chrome, existen controles de ventana para activar o desactivar todos los diseños disponibles. Si eliges la opción de orientación correcta, puedes asegurarte de que el usuario tenga el diseño correcto después de iniciar la app. Si una app está disponible en modo vertical y horizontal, establécelo de forma predeterminada, si es posible. Una vez que se configura esa opción, se recuerda en cada app.
  • Intenta evitar cambios de orientación innecesarios. Por ejemplo, si la orientación de la actividad es vertical, pero la app llama a setRequestedOrientation(LANDSCAPE) durante el tiempo de ejecución, se produce un cambio de tamaño innecesario de la ventana, que resulta molesto para el usuario y podría reiniciar la app porque la app no puede controlarlo. Es mejor configurar la orientación una vez, por ejemplo, en el manifiesto, y solo cambiarla si es necesario.

Otras consideraciones

A continuación, se incluyen algunos aspectos que debes tener en cuenta cuando trabajas con apps para Android en ChromeOS:

  • No llames al objeto finish() en el método onDestroy de tu actividad. Esto hace que la app se cierre cuando se cambia el tamaño y no se reinicie.
  • No uses tipos de ventana que no sean compatibles, como los objetos TYPE_KEYGUARD o TYPE_APPLICATION_MEDIA.
  • Almacena en caché los objetos que se asignaron previamente para que la actividad se reinicie rápidamente.
  • Si no quieres que el usuario cambie el tamaño de tu app, especifica android:resizeableActivity=false en tu archivo de manifiesto.
  • Prueba la app para asegurarte de que controle los cambios en el tamaño de la ventana de forma adecuada.