Emuladores para cada formato

# Android Studio → Device Manager → Create device

# Tablet:
# → "Pixel Tablet" (10.95" 2560x1600) — el más cercano a hardware real de Google
# → "Nexus 9" para hardware más viejo compatible
# → API 33+ para tener las últimas APIs de large screen

# Foldable:
# → "7.6" Fold-in with outer display" — simula el Galaxy Z Fold
# → Permite plegar/desplegar desde el emulador
# → API 33+

# ChromeOS:
# → No hay un emulador directo en Android Studio
# → Alternativa: usar un emulador de tablet y redimensionar la ventana manualmente
# → O instalar Chrome OS en una VM para testing real

# Android TV:
# → "Android TV (1080p)" — TV estándar
# → "Android TV (4K)" — TV 4K
# → API 33+ para las últimas APIs

# FireTV (Amazon) — popular pero no incluido en Android Studio por default
# → Descargar el emulador de Amazon Developer Portal

Resizable Emulator — el más útil para tablets

# "Resizable (Experimental)" — un emulador que puede cambiar de forma:
# → Phone: 411 x 891 dp
# → Tablet: 1280 x 800 dp  
# → Unfolded: 841 x 673 dp (foldable extendido)
# → Desktop: 1920 x 1080 dp (ChromeOS)

# Cambiar el tamaño desde la barra lateral del emulador o via ADB:
adb shell wm size 1280x800dp    # cambiar a resolución de tablet
adb shell wm density 240         # cambiar densidad
adb shell wm size reset          # volver al tamaño original

# Para simular el estado de un foldable:
# Desde el emulador: botón "Fold/Unfold" en la barra lateral
# Via ADB:
adb shell cmd device_state state 1    # plegar
adb shell cmd device_state state 2    # extender

Testear layouts con WindowSizeClass en unit tests

// Testear que el layout correcto aparece según el WindowSizeClass
@RunWith(AndroidJUnit4::class)
class NavegacionAdaptativaTest {

    @get:Rule
    val composeTestRule = createComposeRule()

    @Test
    fun `en compact se muestra BottomNavigationBar`() {
        composeTestRule.setContent {
            // Simular WindowSizeClass COMPACT
            val windowSizeClass = WindowSizeClass.calculateFromSize(DpSize(400.dp, 800.dp))
            AppConNavegacionAdaptativa(windowSizeClass = windowSizeClass)
        }

        // Verificar que el NavigationBar (bottom) está presente
        composeTestRule.onNode(hasRole(Role.Tab)).assertIsDisplayed()
        // Verificar que el NavigationRail NO está presente
        composeTestRule.onNodeWithTag("navigation-rail").assertDoesNotExist()
    }

    @Test
    fun `en expanded se muestra NavigationDrawer`() {
        composeTestRule.setContent {
            val windowSizeClass = WindowSizeClass.calculateFromSize(DpSize(1000.dp, 800.dp))
            AppConNavegacionAdaptativa(windowSizeClass = windowSizeClass)
        }

        composeTestRule.onNodeWithTag("navigation-drawer").assertIsDisplayed()
        composeTestRule.onNodeWithTag("bottom-navigation").assertDoesNotExist()
    }

    @Test
    fun `list-detail en expanded muestra dos paneles`() {
        composeTestRule.setContent {
            val windowSizeClass = WindowSizeClass.calculateFromSize(DpSize(1000.dp, 800.dp))
            PantallaProductosAdaptativa(windowSizeClass = windowSizeClass)
        }

        // En expanded, lista y detalle se muestran simultáneamente
        composeTestRule.onNodeWithTag("lista-panel").assertIsDisplayed()
        composeTestRule.onNodeWithTag("detalle-panel").assertIsDisplayed()
    }
}

Espresso en Android TV — navegación por D-pad

// Los tests instrumentados de TV usan Espresso pero con acciones de D-pad
@RunWith(AndroidJUnit4::class)
class TVNavigationTest {

    @get:Rule
    val activityRule = ActivityScenarioRule(TVMainActivity::class.java)

    @Test
    fun `navegar con dpad selecciona el item correcto`() {
        // Dar focus inicial al primer item
        onView(withId(R.id.primer_item)).perform(click())

        // Presionar D-pad derecha para mover el focus
        onView(withId(R.id.lista_horizontal))
            .perform(pressKey(KeyEvent.KEYCODE_DPAD_RIGHT))

        // Verificar que el segundo item está enfocado
        onView(withId(R.id.segundo_item))
            .check(matches(hasFocus()))

        // Presionar OK para seleccionar
        onView(withId(R.id.segundo_item))
            .perform(pressKey(KeyEvent.KEYCODE_DPAD_CENTER))

        // Verificar que se abrió el detalle
        onView(withId(R.id.detalle_contenido)).check(matches(isDisplayed()))
    }

    @Test
    fun `back button navega correctamente`() {
        // Navegar a la pantalla de detalle
        onView(withId(R.id.primer_item)).perform(click())
        onView(withId(R.id.primer_item)).perform(pressKey(KeyEvent.KEYCODE_DPAD_CENTER))

        // Verificar que estamos en el detalle
        onView(withId(R.id.detalle_contenido)).check(matches(isDisplayed()))

        // Presionar Back
        pressBack()

        // Verificar que volvimos a la lista
        onView(withId(R.id.lista_contenidos)).check(matches(isDisplayed()))
    }
}

Checklist antes de publicar en tablets y TV

# ── TIER 3 — Large Screen Ready (mínimo) ─────────────────────
# ✓ La app no crashea en tablet landscape
# ✓ La app no crashea al rotar en tablet
# ✓ Los elementos de la UI no se cortan ni quedan fuera de pantalla
# ✓ El texto es legible (no demasiado grande por el scaling)
# ✓ Los diálogos y bottom sheets tienen tamaño razonable en pantalla grande

# ── TIER 2 — Large Screen Optimized ──────────────────────────
# ✓ La navegación usa NavigationRail/Drawer en Medium/Expanded
# ✓ El contenido usa el espacio extra (más columnas, más info visible)
# ✓ La orientación landscape se ve bien (no es portrait estirado)
# ✓ Los touch targets funcionan con mouse/trackpad

# ── TIER 1 — Large Screen Differentiated ─────────────────────
# ✓ Patrón list-detail en pantallas Expanded
# ✓ La app responde correctamente a foldables (si aplica)
# ✓ Atajos de teclado para acciones frecuentes
# ✓ Click derecho con ContextMenu donde tiene sentido

# ── ANDROID TV ───────────────────────────────────────────────
# ✓ Todos los elementos interactivos son alcanzables con D-pad
# ✓ El elemento enfocado es visualmente obvio
# ✓ El focus inicial al entrar a cada pantalla está bien configurado
# ✓ Back navigation funciona correctamente
# ✓ Texto legible a 3 metros
# ✓ Márgenes de 48dp en todos los bordes
# ✓ No hay elementos que requieran touch o gestos

Play Console — Large Screen issues

# Google Play Console → Android vitals → Large Screen issues
# Muestra automáticamente problemas detectados en dispositivos reales:
# → Crashes en tablets y foldables de usuarios reales
# → Screenshots de cómo se ve la app en cada dispositivo
# → Rating específico por tipo de dispositivo

# Pre-launch report — verificar antes de publicar:
# Play Console → Testing → Pre-launch report
# Google corre la app en dispositivos reales (tablets incluidas)
# y reporta crashes y screenshots

# Large Screen Quality Badge:
# Las apps que cumplen los criterios de Tier 1-3 reciben badges visibles
# en Play Store que aumentan la conversión
# Para aplicar: Play Console → Store presence → Large screen info