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