Cómo brindar compatibilidad con diferentes tamaños de pantalla

La compatibilidad con diferentes tamaños de pantalla brinda a tu app el acceso a una mayor cantidad de usuarios y una mayor variedad de dispositivos.

Para admitir tantos tamaños de pantalla como sea posible, los diseños de tu app deben ser responsivos y adaptables. Los diseños responsivos o adaptables proporcionan una experiencia del usuario optimizada sin importar el tamaño de la pantalla, lo que permite que tu app funcione en teléfonos, tablets, dispositivos plegables y con Chrome OS, en orientaciones verticales y horizontales, y en configuraciones que pueden cambiar de tamaño, como el modo multiventana.

Clases de tamaño de ventana

Las clases de tamaño de ventana son un conjunto de puntos de interrupción de viewports bien definidos que te ayudan a diseñar, desarrollar y probar diseños de aplicaciones adaptables y responsivos. Se eligieron específicamente a los efectos de equilibrar la simplicidad del diseño con la flexibilidad y optimizar la app en casos únicos.

Las clases de tamaño de ventana categorizan el área de visualización disponible para tu app como compacta, mediana o expandida. El ancho y la altura disponibles se clasifican por separado, por lo que en cualquier momento, tu app tiene dos clases de tamaño de ventana: una para el ancho y otra para la altura. Por lo general, el ancho disponible es más importante que la altura disponible debido a la ubicuidad del desplazamiento vertical. Por lo tanto, es probable que la clase de tamaño de ancho de ventana sea más relevante para la IU de tu app.

Figura 1: Representaciones de clases de tamaños de ventana basadas en el ancho
Figura 2: Representaciones de clases de tamaños de ventana basadas en el alto

Como se indicó antes, los puntos de interrupción te permiten seguir pensando en los diseños en términos de dispositivos y configuraciones. Cada punto de interrupción de clase de tamaño representa la mayoría de los casos en cada dispositivo típico, lo que puede ser un marco de referencia útil cuando piensas en la forma de tus diseños basados en puntos de interrupción.

Clase de tamaño Punto de interrupción Representación del dispositivo
Ancho compacto Menos de 600 dp 99.96% de los teléfonos en orientación vertical
Ancho medio 600 dp o más 93.73% de las tablets en orientación vertical

Pantallas internas grandes y desplegadas en orientación vertical

Ancho expandido 840 dp o más 97.22% de las tablets en orientación horizontal

Pantallas internas grandes y desplegadas en orientación horizontal

Altura compacta Menos de 480 dp 99.78% de los teléfonos en orientación horizontal
Altura media 480 dp o más 96.56% de las tablets en orientación horizontal

97.59% de los teléfonos en orientación vertical

Alto expandido 900 dp o más 94.25% de las tablets en orientación vertical

Si bien puede ser útil visualizar las clases de tamaño como dispositivos físicos, las clases de tamaño de ventana no están determinadas explícitamente por el tamaño de la pantalla del dispositivo. Las clases de tamaño de ventana no están diseñadas para la lógica isTablet-type. En cambio, están determinadas por el tamaño de ventana disponible para tu aplicación, independientemente del tipo de dispositivo en el que se ejecute, lo que tiene dos consecuencias importantes:

  • Los dispositivos físicos no garantizan una clase específica de tamaño de ventana. El espacio de pantalla disponible para tu app puede diferir del tamaño de la pantalla del dispositivo por varios motivos. En los dispositivos móviles, el modo de pantalla dividida puede particionar la pantalla entre dos aplicaciones. En Chrome OS, las apps para Android se pueden presentar en ventanas de formato libre cuyo tamaño puede cambiar de forma arbitraria. Los dispositivos plegables pueden tener dos pantallas de diferentes tamaños a las que se puede acceder de forma individual al plegar o desplegar el dispositivo.

  • La clase de tamaño de ventana puede cambiar durante el ciclo de vida de la app. Mientras se ejecuta la app, los cambios de orientación, la realización de varias tareas y el plegado y desplegado del dispositivo pueden impactar en el espacio de pantalla disponible. Como resultado, la clase de tamaño de ventana es dinámica, y la IU de tu app debería adaptarse según corresponda.

Las clases de tamaño de ventana se asignan a los puntos de interrupción de diseño en la cuadrícula de diseño responsivo de Material Design. Usa clases de tamaño de ventana para tomar decisiones generales en torno al diseño de la aplicación, por ejemplo, si usarás un diseño canónico específico para aprovechar el espacio de pantalla adicional.

Las apps basadas en vistas deben calcular la clase de tamaño de ventana en función de las métricas actuales de la ventana que proporciona la biblioteca WindowManager de Jetpack. En el siguiente código de ejemplo de Views (Kotlin) y Views (Java), se muestra un ejemplo de cómo calcular la clase de tamaño de ventana según los puntos de interrupción y recibir actualizaciones cuando cambia.

Las apps basadas en Compose deben usar la biblioteca material3-window-size-class para calcular un WindowSizeClass basado en las métricas de ventana actuales con calculateWindowSizeClass().

Vistas

enum class WindowSizeClass { COMPACT, MEDIUM, EXPANDED }

class MainActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // ...

        // Replace with a known container that you can safely add a
        // view to where it won't affect the layout and the view
        // won't be replaced.
        val container: ViewGroup = binding.container

        // Add a utility view to the container to hook into
        // View.onConfigurationChanged. This is required for all
        // activities, even those that don't handle configuration
        // changes. We also can't use Activity.onConfigurationChanged,
        // since there are situations where that won't be called when
        // the configuration changes. View.onConfigurationChanged is
        // called in those scenarios.
        container.addView(object : View(this) {
            override fun onConfigurationChanged(newConfig: Configuration?) {
                super.onConfigurationChanged(newConfig)
                computeWindowSizeClasses()
            }
        })

        computeWindowSizeClasses()
    }

    private fun computeWindowSizeClasses() {
        val metrics = WindowMetricsCalculator.getOrCreate()
            .computeCurrentWindowMetrics(this)

        val widthDp = metrics.bounds.width() /
            resources.displayMetrics.density
        val widthWindowSizeClass = when {
            widthDp < 600f -> WindowSizeClass.COMPACT
            widthDp < 840f -> WindowSizeClass.MEDIUM
            else -> WindowSizeClass.EXPANDED
        }

        val heightDp = metrics.bounds.height() /
            resources.displayMetrics.density
        val heightWindowSizeClass = when {
            heightDp < 480f -> WindowSizeClass.COMPACT
            heightDp < 900f -> WindowSizeClass.MEDIUM
            else -> WindowSizeClass.EXPANDED
        }

        // Use widthWindowSizeClass and heightWindowSizeClass.
    }
}

Vistas

public enum WindowSizeClass { COMPACT, MEDIUM, EXPANDED }

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // ...

        // Replace with a known container that you can safely add a
        // view to where it won't affect the layout and the view
        // won't be replaced.
        ViewGroup container = binding.container;

        // Add a utility view to the container to hook into
        // View.onConfigurationChanged. This is required for all
        // activities, even those that don't handle configuration
        // changes. We also can't use Activity.onConfigurationChanged,
        // since there are situations where that won't be called when
        // the configuration changes. View.onConfigurationChanged is
        // called in those scenarios.
        container.addView(new View(this) {
            @Override
            protected void onConfigurationChanged(Configuration newConfig) {
                super.onConfigurationChanged(newConfig);
                computeWindowSizeClasses();
            }
        });

        computeWindowSizeClasses();
    }

    private void computeWindowSizeClasses() {
        WindowMetrics metrics = WindowMetricsCalculator.getOrCreate()
                .computeCurrentWindowMetrics(this);

        float widthDp = metrics.getBounds().width() /
                getResources().getDisplayMetrics().density;
        WindowSizeClass widthWindowSizeClass;

        if (widthDp < 600f) {
            widthWindowSizeClass = WindowSizeClass.COMPACT;
        } else if (widthDp < 840f) {
            widthWindowSizeClass = WindowSizeClass.MEDIUM;
        } else {
            widthWindowSizeClass = WindowSizeClass.EXPANDED;
        }

        float heightDp = metrics.getBounds().height() /
                getResources().getDisplayMetrics().density;
        WindowSizeClass heightWindowSizeClass;

        if (heightDp < 480f) {
            heightWindowSizeClass = WindowSizeClass.COMPACT;
        } else if (heightDp < 900f) {
            heightWindowSizeClass = WindowSizeClass.MEDIUM;
        } else {
            heightWindowSizeClass = WindowSizeClass.EXPANDED;
        }

        // Use widthWindowSizeClass and heightWindowSizeClass.
    }
}

Compose

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            val windowSizeClass = calculateWindowSizeClass(this)
            MyApp(windowSizeClass)
        }
    }
}

Una vez que observes las clases de tamaño de ventana en tu app, estarás listo para comenzar a cambiar tu diseño en función de la clase de tamaño de ventana actual.

Si quieres aprender a usar las clases de tamaño de ventana para que los diseños sean responsivos, consulta lo siguiente:

Lista de tareas para admitir diferentes clases de tamaño de ventana

A medida que realices cambios en el diseño, prueba su comportamiento en todos los rangos de tamaños de ventana, especialmente en los anchos de puntos de interrupción compacto, mediano y expandido.

Si ya tienes un diseño destinado a pantallas compactas, primero debes optimizarlo para la clase de tamaño de ancho expandido, ya que brinda más espacio para cambios adicionales de contenido o diseño. Luego, decide qué diseño es conveniente para la clase de tamaño mediano. Te recomendamos que agregues un diseño especializado para el tamaño de ancho de pantalla mediano.

Para brindar una experiencia del usuario mejorada, agrega funcionalidades que se apliquen específicamente a tu app, como compatibilidad con posiciones plegables y optimizaciones para la compatibilidad con entradas de teclado, mouse y pluma stylus.

Para obtener más información sobre los aspectos que hacen que una app resulte excelente en todos los dispositivos y tamaños de pantalla, consulta el artículo sobre la calidad de apps para pantallas grandes.

Diseño responsivo

El primer paso para admitir una variedad de factores de forma de dispositivos es crear un diseño que reaccione a variaciones en el tamaño de la pantalla.

ConstraintLayout

La mejor manera de crear un diseño responsivo es usar ConstraintLayout como diseño base en tu IU. ConstraintLayout te permite especificar la posición y el tamaño de cada vista según las relaciones espaciales con otras vistas en el diseño. De esta manera, todas las vistas pueden moverse y cambiar de tamaño a medida que cambia el tamaño de la pantalla.

La forma más fácil de compilar un diseño con ConstraintLayout es usar el editor de diseño de Android Studio, ya que te permite arrastrar nuevas vistas al diseño, aplicar restricciones relacionadas con las vistas principales y secundarias, y establecer propiedades de vista, todo sin la necesidad de editar manualmente ningún archivo XML.

Figura 3: El editor de diseño en Android Studio muestra un archivo ConstraintLayout.

Para obtener más información, consulta Cómo compilar una IU responsiva con ConstraintLayout.

Ancho y altura responsivos

A fin de asegurarte de que tu diseño responda a diferentes tamaños de pantalla, usa wrap_content, match_parent o 0dp (match constraint) para el ancho y la altura de la mayoría de los componentes de la vista, en lugar de valores hard-coded:

  • wrap_content: Habilita la vista a fin de establecer su tamaño según lo necesario para adaptarse al contenido de la vista.
  • match_parent: Habilita la vista para expandirse tanto como sea posible dentro de la vista superior.
  • 0dp (match constraint): En un ConstraintLayout, similar a match_parent. Permite que la vista ocupe todo el espacio disponible dentro de las restricciones de la vista.

Por ejemplo:

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/lorem_ipsum" />

En la Figura 4, se muestra cómo se ajustan el ancho y la altura de TextView a medida que cambia el ancho de la pantalla con la orientación del dispositivo.

Figura 4: Una TextView responsiva

El elemento TextView establece su ancho para llenar todo el espacio disponible (match_parent) y su altura a la cantidad exacta que se requiera por la altura del texto contenido (wrap_content), lo que permite que la vista se adapte a diferentes tamaños de pantalla y distintos volúmenes de texto.

Si usas un LinearLayout, también puedes expandir las vistas secundarias según el peso del diseño, de modo que las vistas ocupen proporcionalmente el espacio disponible. Sin embargo, el uso de ponderaciones en un LinearLayout anidado requiere que el sistema realice varios pases de diseño a fin de determinar el tamaño de cada vista, lo que ralentiza el rendimiento de la IU.

ConstraintLayout puede crear casi todos los diseños posibles con LinearLayout sin afectar el rendimiento, por lo que debes intentar convertir tu LinearLayout anidado en ConstraintLayout. Luego, puedes definir los diseños ponderados mediante cadenas de restricciones.

Diseño adaptable

El diseño de tu app siempre debe adaptarse a diferentes tamaños de pantalla. Sin embargo, incluso un diseño responsivo no puede proporcionar la mejor experiencia del usuario en todos los dispositivos. Por ejemplo, la IU que diseñes para un teléfono probablemente no brinde una experiencia óptima en una tablet. El diseño adaptable ofrece diseños alternativos optimizados para diferentes dimensiones de pantalla.

SlidingPaneLayout para ver IU de listas y detalles

Por lo general, una IU de listas y detalles proporciona una experiencia del usuario diferente en pantallas de diferentes tamaños. En pantallas grandes, los paneles de lista y de detalles suelen estar uno al lado del otro. Cuando se selecciona un elemento de la lista, la información del elemento se muestra en el panel de detalles sin cambiar la IU; los dos paneles permanecen uno al lado del otro. Sin embargo, en pantallas pequeñas, los dos paneles se muestran por separado, y cada panel ocupa toda el área de visualización. Cuando se selecciona un elemento del panel de lista, el panel de detalles (que contiene la información del elemento seleccionado) reemplaza al panel de lista. La navegación hacia atrás reemplaza al panel de detalles por la lista.

SlidingPaneLayout administra la lógica a fin de determinar cuál de las dos experiencias del usuario es apropiada para el tamaño de ventana actual:

<?xml version="1.0" encoding="utf-8"?>
<androidx.slidingpanelayout.widget.SlidingPaneLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="280dp"
        android:layout_height="match_parent"
        android:layout_gravity="start" />

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="300dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        app:defaultNavHost="true"
        app:navGraph="@navigation/item_navigation" />

</androidx.slidingpanelayout.widget.SlidingPaneLayout>

Los atributos layout_width y layout_weight de las dos vistas que se encuentran en SlidingPaneLayout determinan el comportamiento de SlidingPaneLayout. En el ejemplo, si la ventana es lo suficientemente grande (tiene al menos 580 dp de ancho) para mostrar ambas vistas, los paneles se muestran uno al lado del otro. Sin embargo, si el ancho es inferior a 580 dp, los paneles se deslizarán uno sobre otro para ocupar toda la ventana de la app.

Si el ancho de la ventana es mayor que el ancho mínimo total especificado (580 dp), se pueden usar valores layout_weight para ajustar el tamaño de los dos paneles de forma proporcional. En el ejemplo, el panel de lista siempre tiene 280 dp de ancho, porque no tiene un peso. Sin embargo, en el panel de detalles, siempre se rellena cualquier espacio horizontal superior a 580 dp debido al layout_weight de la vista.

Recursos de diseño alternativos

Para adaptar el diseño de la IU a diversos tamaños de pantalla, usa diseños alternativos identificados con calificadores de recursos.

Figura 5: La misma app en pantallas de distintos tamaños usa un diseño diferente para cada una.

Puedes proporcionar diseños adaptables y específicos para cada pantalla mediante la creación de otros directorios res/layout/ en el código fuente de tu app. Crea un directorio para cada configuración de pantalla que requiera un diseño diferente. Luego, agrega un calificador de configuración de pantalla al nombre del directorio layout (por ejemplo, layout-w600dp para pantallas que tengan 600 dp de ancho disponible).

Los calificadores de configuración representan el espacio de pantalla visible disponible para la IU de tu app. El sistema considera cualquier decoración (como la barra de navegación) y cambio en la configuración de la ventana (como el modo multiventana) al seleccionar el diseño de la app.

Para crear un diseño alternativo en Android Studio (con la versión 3.0 o una posterior) haz lo siguiente:

  1. Abre tu diseño predeterminado y, luego, haz clic en Orientation for Preview , en la barra de herramientas.
  2. En la lista desplegable, haz clic para crear una variante sugerida, como Create Landscape Variation, o haz clic en Create Other.
  3. Si eliges Create Other, aparecerá la opción Select Resource Directory. Aquí, deberás seleccionar un calificador de pantalla del lado izquierdo y agregarlo a la lista de Chosen qualifiers. Cuando termines de agregar calificadores, haz clic en OK. (Consulta las siguientes secciones para obtener información sobre los calificadores de tamaños de pantalla).

Se creará un duplicado de tu archivo de diseño predeterminado en el nuevo directorio de diseño para que puedas comenzar a personalizar el diseño de esa variante de pantalla.

Calificador de ancho mínimo

El calificador de tamaño de pantalla de ancho mínimo te permite proporcionar diseños alternativos para pantallas que tienen un ancho mínimo medido en píxeles independientes de la densidad (dp o dip).

Al describir el tamaño de la pantalla como una medida de dp, Android te permite crear diseños para dimensiones de pantalla específicas sin tener en cuenta las diferentes densidades de píxeles.

Por ejemplo, puedes crear un diseño llamado main_activity que esté optimizado para teléfonos y tablets mediante la creación de diferentes versiones del archivo en distintos directorios de la siguiente manera:

res/layout/main_activity.xml           # For phones (smaller than 600dp smallest width)
res/layout-sw600dp/main_activity.xml   # For 7” tablets (600dp wide or wider)

El calificador de ancho mínimo especifica el lado más pequeño de la pantalla, independientemente de la orientación actual del dispositivo, por lo que es una manera sencilla de especificar el tamaño de pantalla total disponible para tu diseño.

A continuación, se muestra cómo los valores de ancho mínimo se corresponden con los tamaños de pantalla típicos:

  • 320 dp: una pantalla típica de teléfono (240 x 320 ldpi, 320 x 480 mdpi, 480 x 800 hdpi, etc.)
  • 480 dp: una pantalla de teléfono grande de ~5" (480 x 800 mdpi)
  • 600 dp: una tablet de 7" (600 x 1,024 mdpi)
  • 720 dp: una tablet de 10" (720 x 1,280 mdpi, 800 x 1,280 mdpi, etcétera)

En la Figura 6, se proporciona una vista más detallada de cómo los diferentes anchos de dp de pantalla generalmente se corresponden con los tamaños y las orientaciones de pantalla diferentes.

Figura 6: Puntos de interrupción de ancho recomendados para admitir diferentes tamaños de pantalla

Los valores del calificador de ancho mínimo son en dp porque lo que importa es la cantidad de espacio de pantalla disponible después de que el sistema considera la densidad de píxeles (no la resolución de píxeles sin procesar).

Los tamaños que especificas con calificadores de recursos como ancho mínimo no son los tamaños de pantalla reales. En su lugar, los tamaños especifican el ancho o alto en unidades dp disponibles para la ventana de tu app. El sistema Android puede usar una parte de la pantalla para la IU del sistema (como la barra del sistema en la parte inferior de la pantalla o la barra de estado en la parte superior). Por lo tanto, es probable que parte de la pantalla no esté disponible para tu diseño. Si tu app se usa en el modo multiventana, solo tendrá acceso al tamaño de la ventana que contiene la app. Cuando cambia el tamaño de la ventana, se activa un cambio de configuración con el nuevo tamaño, que permite que el sistema seleccione un archivo de diseño apropiado. Por lo tanto, los tamaños de calificador de recursos que declares deben especificar solo el espacio que necesita tu app. El sistema considera cualquier espacio que usa la IU del sistema al proporcionar espacio para el diseño.

Calificador de ancho disponible

En lugar de cambiar el diseño en función del ancho mínimo de la pantalla, puedes hacerlo según el ancho o el alto disponibles actualmente. Por ejemplo, es posible que quieras usar un diseño de doble panel siempre que la pantalla proporcione un ancho mínimo de 600 dp, lo que podría variar en función de si el dispositivo se encuentra en orientación horizontal o vertical. En ese caso, deberías usar el calificador de ancho disponible de la siguiente manera:

res/layout/main_activity.xml         # For phones (smaller than 600dp available width)
res/layout-w600dp/main_activity.xml  # For 7” tablets or any screen with 600dp available width
                                     # (possibly landscape phones)

Si la altura disponible es importante para tu app, puedes usar el calificador de altura disponible. Por ejemplo, layout-h600dp para pantallas con al menos 600 dp de alto de pantalla.

Calificadores de orientación

Si bien es posible admitir todas las variaciones de tamaño con solo usar combinaciones de calificadores de ancho mínimo y ancho disponible, es posible que también desees cambiar la experiencia del usuario cuando este cambie entre la orientación vertical y la horizontal.

Para eso, puedes agregar los calificadores port o land a los nombres del directorio de recursos. Solo asegúrate de que los calificadores de orientación aparezcan después de los calificadores de tamaño. Por ejemplo:

res/layout/main_activity.xml                # For phones
res/layout-land/main_activity.xml           # For phones in landscape
res/layout-sw600dp/main_activity.xml        # For 7” tablets
res/layout-sw600dp-land/main_activity.xml   # For 7” tablets in landscape

Para obtener más información sobre todos los calificadores de configuración de la pantalla, consulta Información general sobre los recursos de las aplicaciones.

Componentes de la IU modularizados con fragmentos

Cuando diseñes tu app para varios tamaños de pantalla, usa fragmentos a fin de extraer la lógica de la IU en componentes individuales para asegurarte de no duplicar innecesariamente el comportamiento de la IU en las actividades. Luego, podrás combinar los fragmentos para crear diseños de varios paneles en pantallas grandes o colocarlos en actividades independientes en pantallas pequeñas.

Por ejemplo, el patrón de detalles de lista (consulta SlidingPaneLayout más arriba) podría implementarse con un fragmento que contenga la lista y otro fragmento con los detalles del elemento de lista. En pantallas grandes, los fragmentos podrían mostrarse uno al lado del otro; en pantallas pequeñas, individualmente en toda la pantalla.

Para obtener más información, consulta la descripción general de Fragments.

Incorporación de actividad

Si tu app consta de varias actividades, incorporarlas te permitirá crear fácilmente una IU adaptable.

La incorporación de actividades muestra varias actividades o varias instancias de la misma actividad simultáneamente en la ventana de tareas de una aplicación. En pantallas grandes, las actividades se pueden mostrar una al lado de la otra: en pantallas pequeñas, apiladas una sobre otra.

Para determinar la manera en que tu app muestra sus actividades, crea un archivo de configuración XML que el sistema utilice para determinar la presentación apropiada según el tamaño de la pantalla. Como alternativa, puedes realizar llamadas a la API de Jetpack WindowManager.

La incorporación de actividades admite cambios de orientación del dispositivo y dispositivos plegables, en los que se apilan y desapilan actividades a medida que el dispositivo rota o pliega y se despliega.

Para obtener más información, consulta Incorporación de actividades.

Tamaños de pantalla y relaciones de aspecto

Prueba tu app en una variedad de tamaños de pantalla y relaciones de aspecto para asegurarte de que la IU se ajuste correctamente.

Android 10 (nivel de API 29) y las versiones posteriores admiten una gran variedad de relaciones de aspecto. Los factores de forma plegables pueden variar desde pantallas altas y angostas, como 21:9 cuando se pliegan, hasta una relación de aspecto cuadrada de 1:1 cuando se despliega.

Para garantizar la compatibilidad con la mayor cantidad posible de dispositivos, prueba tus apps con tantas relaciones de aspecto como puedas.

Figura 7: Relaciones de aspecto de la pantalla

Si no puedes admitir algunas relaciones de aspecto, usa maxAspectRatio y minAspectRatio para indicar las relaciones más altas y más bajas que puede admitir tu app. En casos en los que las pantallas superan estos límites, es posible que se establezca el modo de compatibilidad en la app.

Si no tienes acceso a dispositivos con todos los tamaños de pantalla que deseas probar, puedes usar Android Emulator para emular casi cualquier tamaño de pantalla.

Si prefieres hacer pruebas en dispositivos reales, pero no los tienes, puedes usar Firebase Test Lab para acceder a dispositivos en el Centro de Datos de Google.

Compatibilidad con tamaños de pantalla específicos

Si no quieres que se ejecute tu app en determinados tamaños de pantalla, puedes establecer límites que especifiquen cuánto puede cambiarse dicho tamaño o incluso restringir los dispositivos que pueden instalar tu app en función de la configuración de la pantalla. Si deseas obtener más información, consulta Cómo declarar una compatibilidad de pantalla restringida.

Recursos adicionales