Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Compatibilidad con Multiventana

Android 7.0 admite la visualización de más de una app a la vez. En dispositivos de mano, se pueden ejecutar dos apps una al lado de la otra o una por encima de la otra en el modo de pantalla dividida. En dispositivos de TV, las apps pueden usar el modo de pantalla en pantalla para continuar la reproducción de video mientras los usuarios interactúan con otra aplicación.

Si tu app está orientada a Android 7.0 (nivel de API 24) o versiones posteriores, puedes configurar la manera en que procesa la visualización multiventana. Por ejemplo, puedes especificar las dimensiones mínimas permitidas de tu actividad. También puedes inhabilitar la visualización multiventana para tu app y asegurarte de que el sistema la muestre solamente en el modo de pantalla completa.

Descripción general

Android permite que varias aplicaciones compartan la pantalla al mismo tiempo. Por ejemplo, un usuario podría dividir la pantalla y ver una página web a la izquierda mientras escribe un correo electrónico a la derecha. La experiencia del usuario depende de la versión del SO Android y del tipo de dispositivo que tenga:

  • Los dispositivos de mano que ejecutan Android 7.0 ofrecen el modo de pantalla dividida. En este modo, el sistema ocupa la pantalla con dos apps y las muestra una al lado de la otra o una encima de la otra. El usuario puede arrastrar la línea que divide las dos aplicaciones para ver una más grande que la otra.
  • A partir de Android 8.0, las apps pueden habilitar de forma automática el modo de pantalla en pantalla. Esto les permite continuar mostrando contenido mientras el usuario explora otras apps o interactúa con ellas.
  • Los fabricantes de dispositivos más grandes pueden optar por habilitar el modo de forma libre, en el que el usuario puede modificar el tamaño de cada actividad como más le guste. Si el fabricante habilita esta función, el dispositivo ofrecerá el modo de forma libre además del modo de pantalla dividida.

Figura 1: Dos apps ejecutándose una al lado de la otra en el modo de pantalla dividida

El usuario puede cambiar al modo multiventana de la siguiente manera:

  • Si el usuario abre la pantalla Recientes y mantiene presionado el título de una actividad, puede arrastrarla a una parte resaltada de la pantalla para usarla en el modo multiventana.
  • Si el usuario mantiene presionado el botón Recientes, el dispositivo coloca la actividad actual en el modo multiventana y abre la pantalla Recientes a fin de permitirle al usuario seleccionar otra actividad para compartir la pantalla.

Los usuarios pueden arrastrar y soltar datos de una actividad a otra mientras estas comparten la pantalla.

Ciclo de vida en el modo multiventana

El modo multiventana no cambia el ciclo de vida de la actividad.

En el modo multiventana, solo está activa en un momento determinado la actividad con la que el usuario interactuó más recientemente. Esta actividad se considera principal y es la única actividad que tiene el estado RESUMED. Todas las demás actividades visibles tienen el estado STARTED, pero no pueden aparecer como RESUMED. No obstante, el sistema les da a esas actividades visibles pero no reanudadas una prioridad más alta que a las actividades que no están visibles. Si el usuario interactúa con una de las actividades visibles, esta se reanuda y la actividad principal anterior pasa al estado STARTED.

Nota: En el modo multiventana, una app puede no aparecer con el estado RESUMED aunque sea visible para el usuario. Es posible que una app necesite seguir ejecutándose mientras no sea la principal. Por ejemplo, una app de reproducción de video en este estado debería seguir mostrando su contenido. Por este motivo, recomendamos que las actividades que reproduzcan videos no pausen la reproducción en respuesta al evento de ciclo de vida ON_PAUSE. En su lugar, la actividad debe comenzar a reproducirse en respuesta a ON_START y pausar la reproducción en respuesta a ON_STOP. Si controlas los eventos de ciclo de vida de forma directa en lugar de utilizar el paquete Lifecycle, detén la reproducción de video en tu controlador onStop() y reanuda la reproducción en onStart().

Cuando el usuario coloca una app en el modo multiventana, el sistema notifica a la actividad de un cambio de configuración, como se especifica en Cómo controlar los cambios de configuración. Esto también sucede cuando el usuario modifica el tamaño de la app o la coloca nuevamente en el modo de pantalla completa. Este cambio tiene en esencia las mismas consecuencias en el ciclo de vida de la actividad que cuando el sistema notifica a la app que el dispositivo cambió del modo vertical al de paisaje, excepto porque se modifican las dimensiones del dispositivo en lugar de intercambiarse solamente. Como se explica en Cómo controlar los cambios de configuración, tu actividad puede procesar el cambio de configuración por sí misma o puede permitir que el sistema destruya la actividad y la vuelva a crear con las nuevas dimensiones.

Si el usuario cambia el tamaño de una ventana y la agranda en cualquier dirección, el sistema modifica el tamaño de la actividad para que coincida con la acción del usuario y emite cambios de configuración según sea necesario. Si la app se retrasa en el dibujo de áreas recientemente expuestas, el sistema rellena de forma temporal esas áreas con el color especificado por el atributo windowBackground o por el atributo de estilo predeterminado windowBackgroundFallback.

Cómo configurar tu app para el modo multiventana

Si tu app está orientada a un nivel de API 24 o superior, puedes configurar si quieres que las actividades de la app admitan la visualización multiventana y cómo quieres que lo hagan. Puedes establecer atributos en tu manifiesto para controlar el tamaño y el diseño. La configuración de atributos de una actividad raíz se aplica a todas las actividades de su pila de tareas. Por ejemplo, si el objeto android:resizeableActivity está configurado en verdadero para la actividad raíz, se puede modificar el tamaño de todas las actividades de la pila de tareas.

Nota: Si compilas una app para varias orientaciones con un nivel de API 23 o inferior, y el usuario utiliza la app en el modo multiventana, el sistema redimensiona la app de manera forzosa. El sistema presenta un cuadro de diálogo en el que se advierte al usuario que la app puede comportarse de forma inesperada. El sistema no modifica el tamaño de apps con orientación fija; si el usuario intenta abrir una de esas aplicaciones en el modo multiventana, la app ocupará toda la pantalla.

android:resizeableActivity

Establece este atributo en el elemento <activity> o <application> de tu manifiesto para habilitar o inhabilitar la visualización en el modo multiventana:

android:resizeableActivity=["true" | "false"]

Si este atributo se establece en verdadero, la actividad puede iniciarse en los modos de pantalla dividida y forma libre. Si el atributo se establece en falso, la actividad no admite el modo multiventana. Si este valor es falso, y el usuario intenta iniciar la actividad en el modo multiventana, la actividad ocupará toda la pantalla.

Si tu app está orientada al nivel de API 24, pero no especificas un valor para este atributo, el valor predeterminado del atributo será "verdadero".

android:supportsPictureInPicture

Establece este atributo en el nodo <activity> de tu manifiesto para indicar si la actividad admite la visualización de pantalla en pantalla. Este atributo se ignora si el objeto android:resizeableActivity es falso.

android:supportsPictureInPicture=["true" | "false"]

Atributos de diseño

Con Android 7.0, el elemento de manifiesto <layout> admite varios atributos que afectan cómo se comporta una actividad en el modo multiventana:

android:defaultWidth
Es el ancho predeterminado de la actividad cuando se inicia en modo de forma libre.
android:defaultHeight
Es la altura predeterminada de la actividad cuando se inicia en modo de forma libre.
android:gravity
Es la ubicación inicial de la actividad cuando se inicia en el modo de forma libre. Consulta la referencia de Gravity para obtener valores adecuados.
android:minHeight, android:minWidth
Son la altura y el ancho mínimos para la actividad tanto en el modo de pantalla dividida como en el de forma libre. Si el usuario mueve la línea divisoria en el modo de pantalla dividida para reducir el tamaño de la actividad a un valor menor al mínimo especificado, el sistema recorta la actividad para ajustarla a los requisitos del usuario.

Por ejemplo, el siguiente código muestra cómo especificar la ubicación y el tamaño predeterminados de una actividad, y su tamaño mínimo, cuando la actividad se visualiza en el modo de forma libre:

<activity android:name=".MyActivity">
    <layout android:defaultHeight="500dp"
          android:defaultWidth="600dp"
          android:gravity="top|end"
          android:minHeight="450dp"
          android:minWidth="300dp" />
</activity>

Cómo controlar correctamente los cambios de la configuración

Si controlas los cambios de la configuración del modo multiventana por tu cuenta, por ejemplo, lo que sucede cuando un usuario cambia el tamaño de una ventana, agrega el atributo android:configChanges a tu manifiesto con al menos los siguientes valores:

<activity
  android:name=".MyActivity"
  android:configChanges="screenSize|smallestScreenSize
      |screenLayout|orientation"
/>

Después de agregar android:configChanges, tu actividad y tus fragmentos recibirán una devolución de llamada a onConfigurationChanged() en lugar de destruirse y volver a crearse. Luego, podrás actualizar manualmente las vistas, volver a cargar los recursos y realizar otras operaciones según sea necesario.

Cómo ejecutar tu app en el modo multiventana

A partir de Android 7.0, el sistema ofrece funcionalidad para admitir apps que pueden ejecutarse en el modo multiventana.

Funciones inhabilitadas en el modo multiventana

Ciertas funciones están inhabilitadas o se ignoran cuando un dispositivo se encuentra en el modo multiventana, ya que no resultan útiles para una actividad que podría estar compartiendo la pantalla del dispositivo con otras actividades o apps. Esas funciones incluyen las siguientes:

  • Algunas opciones de personalización de la IU del sistema están inhabilitadas; por ejemplo, las apps no pueden ocultar la barra de estado si no se están ejecutando en el modo de pantalla completa.
  • El sistema ignora los cambios del atributo android:screenOrientation.

Búsqueda y notificaciones de cambios en el modo multiventana

Activity ofrece los siguientes métodos para admitir la visualización multiventana.

isInMultiWindowMode()
Realiza una llamada para averiguar si la actividad está en el modo multiventana.
isInPictureInPictureMode()
Realiza una llamada para averiguar si la actividad está en el modo de pantalla en pantalla.

Nota: El modo de pantalla en pantalla es un caso especial del modo multiventana. Si myActivity.isInPictureInPictureMode() muestra un valor verdadero, myActivity.isInMultiWindowMode() también muestra el mismo valor.

onMultiWindowModeChanged()
El sistema llama a este método siempre que la actividad entra en el modo multiventana o sale de él. El sistema le pasa al método el valor verdadero si la actividad ingresa al modo multiventana y el valor falso si sale de él.
onPictureInPictureModeChanged()
El sistema llama a este método siempre que la actividad entra en el modo de pantalla en pantalla o sale de él. El sistema le pasa al método el valor verdadero si la actividad ingresa al modo de pantalla en pantalla y el valor falso si sale de él.

La clase Fragment expone versiones de muchos de estos métodos, como Fragment.onMultiWindowModeChanged().

Cómo ingresar al modo de pantalla en pantalla

Para que una actividad ingrese al modo de pantalla en pantalla, debes llamar a Activity.enterPictureInPictureMode(). Este método no tiene efecto si el dispositivo no admite el modo de pantalla en pantalla. Para obtener más información, consulta la documentación sobre la función Pantalla en pantalla.

Cómo iniciar nuevas actividades en el modo multiventana

Cuando inicias una nueva actividad, puedes indicar que la actividad nueva se debe mostrar adyacente a la actual si es posible. Para hacer esto, usa la marca de intent FLAG_ACTIVITY_LAUNCH_ADJACENT. Esta marca le indica al sistema que intente crear la actividad nueva junto a la actividad que la inició, de modo que las dos compartan la pantalla. El sistema hace su mejor esfuerzo para llevarlo a cabo, pero no se garantiza que lo logre.

Si un dispositivo está en el modo de forma libre e inicias una actividad nueva, puedes especificar las dimensiones y la ubicación de la pantalla de la nueva actividad llamando a ActivityOptions.setLaunchBounds(). Este método no tiene efecto si el dispositivo no está en el modo multiventana.

Nota: Si inicias una actividad en una pila de tareas, esa actividad reemplazará la que esté en pantalla y heredará todas sus propiedades multiventana. Si quieres iniciar la actividad nueva en una ventana independiente en el modo multiventana, debes iniciarla en una nueva pila de tareas.

Cómo agregar compatibilidad con arrastrar y soltar

Los usuarios pueden arrastrar y soltar datos de una actividad a otra mientras las dos actividades comparten la pantalla. (Antes de Android 7.0, los usuarios solo podían arrastrar y soltar datos dentro de una sola actividad). Por este motivo, te recomendamos que agregues la funcionalidad de arrastrar y soltar a tu app si aún no la admite.

DragAndDropPermissions
Es el objeto token responsable de especificar los permisos otorgados a la app que recibe datos mediante la funcionalidad de arrastrar y soltar.
View.startDragAndDrop()
Alias de View.startDrag(). Para habilitar la funcionalidad de arrastrar y soltar entre diferentes actividades, pasa la marca DRAG_FLAG_GLOBAL. Si necesitas otorgar permisos de URI a la actividad receptora, pasa los marcadores DRAG_FLAG_GLOBAL_URI_READ o DRAG_FLAG_GLOBAL_URI_WRITE según corresponda.
View.cancelDragAndDrop()
Cancela una operación de arrastre actualmente en curso. Solo lo puede llamar la app que originó la operación de arrastre.
View.updateDragShadow()
Reemplaza la sombra de arrastre por una operación de arrastre actualmente en curso. Solo lo puede llamar la app que originó la operación de arrastre.
Activity.requestDragAndDropPermissions()
Solicita los permisos para los URI de contenido que se pasan con el ClipData incluido en un DragEvent.
DragAndDropPermissions.release()
Actualiza los permisos necesarios para acceder a los datos en la URI de contenido que se proporcionan en ClipData. Si no llamas a este método, los permisos se actualizan automáticamente cuando se destruye la actividad que los contiene.

Cómo probar la compatibilidad de tu app con el modo multiventana

Independientemente de si tu app está orientada al nivel de API 24 o a alguno superior, debes verificar cómo se comporta en el modo multiventana en caso de que un usuario intente iniciarla en un dispositivo que ejecute Android 7.0 o una versión posterior.

Cómo configurar un dispositivo de prueba

Si un dispositivo ejecuta Android 7.0 o una versión posterior, automáticamente admite el modo de pantalla dividida.

Si tu app está orientada al nivel de API 23 o inferior

Si tu app está orientada al nivel de API 23 o inferior, y el usuario intenta usarla en el modo multiventana, el sistema cambia el tamaño de la app de manera forzosa, a menos que la aplicación declare una orientación fija.

Si tu app no declara una orientación fija, debes iniciarla en un dispositivo con Android 7.0 o una versión posterior, e intentar colocar la app en el modo de pantalla dividida. Cuando se modifique el tamaño de la app de manera forzosa, verifica que la experiencia del usuario sea aceptable.

Si la app declara una orientación fija, debes intentar colocarla en el modo multiventana. Cuando lo hagas, verifica que la app continúe en el modo de pantalla completa.

Si admites el modo multiventana

Si tu app está orientada al nivel de API 24 o superior, y no inhabilita la compatibilidad con el modo multiventana, verifica el siguiente comportamiento tanto en el modo de pantalla dividida como en el de forma libre.

  • Inicia la app en el modo de pantalla completa y, luego, cambia al modo multiventana manteniendo presionado el botón Recientes. Verifica que la app pase de un modo al otro correctamente.
  • Inicia la app directamente en el modo multiventana y verifica que se inicie en forma correcta. Puedes iniciar una app en el modo multiventana presionando el botón Recientes y, luego, manteniendo presionada la barra de título de la app y arrastrándola a una de las áreas resaltadas de la pantalla.
  • Cambia el tamaño de tu app en el modo de pantalla dividida arrastrando la línea divisoria. Verifica que la app cambie de tamaño sin presentar fallas y que estén visibles los elementos necesarios de la IU.
  • Si especificaste dimensiones mínimas para tu app, intenta cambiar el tamaño a dimensiones menores que las especificadas. Verifica que no puedas modificar el tamaño de la app para que sea más pequeña que la dimensión mínima especificada.
  • En todas las pruebas, verifica que el rendimiento de la app sea aceptable. Por ejemplo, verifica que la actualización de la IU después de cambiar el tamaño de la app no tarde mucho.

Lista de tareas para pruebas

Para verificar el rendimiento de tu app en el modo multiventana, realiza las siguientes operaciones. Debes probar estas operaciones tanto en el modo de pantalla dividida como en el modo multiventana, excepto cuando se indique algo diferente.

  • Ingresa en el modo multiventana y luego sal de él.
  • Pasa de tu app a otra y verifica que la app se comporte correctamente mientras esté visible pero inactiva. Por ejemplo, si tu app está reproduciendo un video, comprueba que este se siga reproduciendo mientras el usuario interactúa con otra aplicación.
  • En el modo de pantalla dividida, prueba a mover la barra divisora para agrandar y achicar la app. Realiza estas operaciones en las configuraciones una al lado de la otra y una encima de la otra. Verifica que la app no presente fallas, que las funcionalidades necesarias estén visibles y que la operación de cambio de tamaño no tarde mucho.
  • Realiza varias operaciones de cambio de tamaño en una sucesión rápida. Verifica que tu app no falle ni pierda memoria. Para obtener información sobre cómo comprobar el uso de memoria de tu app, utiliza el Generador de perfiles de memoria de Android Studio.
  • Usa tu app en diferentes configuraciones de ventanas y verifica que se comporte correctamente. Verifica que el texto sea legible y que los elementos de la IU sean lo suficientemente grandes como para interactuar con ellos.

Si inhabilitaste la compatibilidad con el modo multiventana

Si inhabilitaste la compatibilidad con el modo multiventana configurando android:resizeableActivity="false", debes iniciar tu app en un dispositivo con Android 7.0 o versiones posteriores, e intentar colocar la aplicación en los modos de forma libre y de pantalla dividida. Cuando lo hagas, verifica que la app continúe en el modo de pantalla completa.

Para obtener más información sobre la compatibilidad con el modo multiventana en Android, consulta Cinco sugerencias para brindar compatibilidad con el modo multiventana en Android N y la app de ejemplo Multi-Window Playground.