Blog
Feature
18 de octubre de 20258 min

Video móvil y arrastrar y soltar en React Native: guía UX

Hay una diferencia entre una aplicación que funciona y una aplicación que dan ganas de usar. Esta diferencia radica en los detalles: la fluidez de una animación, la reactividad de un gesto, el tiempo de carga de una pantalla. En octubre de 2025, pasé dos semanas trabajando en tres características que no tenían nada en común excepto un objetivo: hacer que TAMSIV fuera moderna y agradable de usar.

Captura de video al estilo TikTok. Arrastrar y soltar para reorganizar las pestañas. Carrusel infinito en el feed. Tres proyectos distintos, una sola obsesión: la sensación de fluidez.

Puntos clave a recordar:
- La compresión de video es indispensable en dispositivos móviles — los archivos brutos pesan decenas de MB
- El arrastrar y soltar de las pestañas utiliza obligatoriamente react-native-gesture-handler, no los componentes nativos
- Un carrusel infinito bien hecho requiere la precarga de los elementos adyacentes
- Guardar el orden de las pestañas en la base de datos permite la persistencia entre dispositivos
- Las microinteracciones son lo que diferencia una aplicación "correcta" de una aplicación "notable"

¿Por qué integrar una captura de video en una aplicación de productividad?

La pregunta parece extraña al principio. Una aplicación de gestión de tareas no necesita video, ¿verdad? En realidad, sí. Cuando creas una nota de voz con TAMSIV, a veces quieres adjuntar una pieza adjunta visual — una foto de un documento, un video de un prototipo, una grabación de pantalla.

Ya había implementado los archivos adjuntos (fotos y documentos). Pero faltaba el video. Y cuando empecé a prototipar la interfaz, me di cuenta de que una captura de video clásica — el componente de cámara bruto de Android — era horrible. Sin estilo, sin fluidez, una experiencia digna de 2015.

La inspiración vino de donde tú esperas: TikTok. No por los videos cortos, sino por la interfaz de captura. Botón central, vista previa a pantalla completa, controles mínimos. Se ha convertido en el estándar UX que los usuarios esperan en 2026.

Persona sosteniendo un smartphone en modo retrato para grabar un video con una interfaz de cámara moderna
La interfaz de captura de video de TAMSIV: inspiración TikTok, ejecución minimalista.

¿Cómo gestionar la compresión de video en dispositivos móviles?

Este es el mayor desafío técnico de la captura de video. Los videos brutos de un smartphone moderno pesan decenas de megabytes por unos pocos segundos. Un iPhone 15 graba en HEVC 4K a 60fps — puede alcanzar los 400 MB por minuto. Incluso en 1080p, un video de 30 segundos pesa fácilmente 50 MB.

Para una aplicación de productividad, esto es inaceptable. Los archivos adjuntos se almacenan en Supabase Storage, y cada MB de egreso cuesta dinero. De hecho, detallé los problemas de egreso en el artículo sobre la reducción de costos de Supabase.

La solución: configurar la captura para limitar la resolución y el bitrate desde el principio. En lugar de capturar en 4K y luego comprimir (lo que consume CPU y batería), configuro el componente de la cámara para capturar directamente en un formato ligero:

  • Resolución: 720p máximo (suficiente para archivos adjuntos)
  • Bitrate: limitado a 2 Mbps
  • Formato: H.264 para compatibilidad universal
  • Duración máxima: 60 segundos (límite voluntario para evitar archivos enormes)

Con estos parámetros, un video de 30 segundos pesa aproximadamente 3 a 5 MB en lugar de 50 MB. Una ganancia de factor 10 que hace que el almacenamiento y la transferencia sean viables.

¿Cuál es la trampa de la pantalla completa en Android?

La vista previa de la cámara a pantalla completa parece trivial. No lo es. En Android, la relación de aspecto de la pantalla (generalmente 19.5:9 o 20:9) no coincide con la relación de aspecto de la cámara (16:9 o 4:3). Resultado: o muestras bandas negras, o recortas la imagen, o la estiras.

Opté por el recorte con un ligero zoom, lo que hace TikTok. La imagen llena toda la pantalla, pero los bordes están ligeramente cortados. El usuario no lo nota. La sensación de inmersión se mantiene.

La segunda trampa: la gestión de la orientación. TAMSIV fuerza el modo retrato para la captura de video (coherente con el uso móvil), pero es necesario interceptar los cambios de orientación del dispositivo para evitar que el video se grabe al revés. Un error clásico que me llevó medio día rastrear.

¿Cómo implementar el arrastrar y soltar de las pestañas?

TAMSIV tiene 6 pestañas principales: Dictáfono, Feed, Agenda, Grupos, Social, Perfil. El orden predeterminado es adecuado para la mayoría de los usuarios, pero algunos prefieren otra disposición. Implementé la reorganización mediante arrastrar y soltar: pulsación larga en una pestaña, arrastrar, soltar.

Pantalla de tableta mostrando una interfaz de aplicación móvil con iconos de pestañas reorganizables mediante arrastrar y soltar
Arrastrar y soltar pestañas: personaliza tu experiencia TAMSIV.

La implementación utiliza react-native-gesture-handler (obligatorio en React Native para gestos complejos) combinado con react-native-reanimated para animaciones fluidas.

El gran inconveniente: gesture-handler obligatorio

Esta es una trampa en la que perdí horas. En un GestureDetector, es obligatorio usar los componentes de react-native-gesture-handlerTouchableOpacity, FlatList, ScrollView — y nunca los de react-native. Los componentes nativos simplemente no reciben eventos táctiles en un contexto de gesture-handler.

El error es vicioso: todo compila, no hay advertencias, pero el arrastrar y soltar no funciona. Pasas horas buscando un problema de lógica cuando es solo una importación incorrecta. Se ha convertido en una regla cardinal del proyecto: en cualquier componente que use gestos, verificar las importaciones.

La persistencia entre dispositivos

El orden de las pestañas se guarda en la base de datos en userProfile.mainTabsOrder. No es solo AsyncStorage local — si el usuario inicia sesión en otro dispositivo o reinstala la aplicación, recupera su configuración. Este detalle parece menor pero contribuye a la sensación de una aplicación "inteligente" que te conoce.

El formato es simple: un array JSON de identificadores de pestañas. ["dictaphone", "agenda", "feed", "groups", "social", "profile"]. Al cargar, la aplicación lee este array y reorganiza la navegación en consecuencia. Si falta una pestaña (por ejemplo, después de agregar una característica), se agrega al final.

¿Cómo funciona el carrusel infinito en el feed?

El feed de TAMSIV muestra un flujo de elementos: tareas, notas, eventos, actividad de gamificación. Cuando haces clic en un elemento, quieres poder navegar al anterior o al siguiente sin volver a la lista. Este es el patrón del carrusel infinito.

La implementación se basa en un componente FlatList horizontal (de react-native-gesture-handler, por supuesto) con un sistema de precarga de elementos adyacentes. Cuando visualizas el elemento N, los elementos N-1 y N+1 ya están cargados en memoria y renderizados fuera de la pantalla.

Persona desplazándose por un feed de contenido en un smartphone con tarjetas e imágenes que se cargan de forma fluida
El carrusel infinito: sin spinner, sin carga visible.

El resultado: sin spinner, sin carga visible. La ilusión de un contenido siempre listo. El deslizamiento es instantáneo. Este tipo de detalle invisible es lo que marca la diferencia entre una aplicación que se usa por obligación y una aplicación que se usa por placer.

El desafío de la memoria

La precarga tiene un costo: la memoria. Si cada elemento del feed contiene imágenes o videos, cargar 3 elementos al mismo tiempo (actual + 2 adyacentes) puede consumir mucha RAM. Implementé un sistema de reciclaje: los elementos lejanos (N-3, N+3 y más allá) se liberan de la memoria. Solo se mantiene la ventana deslizante de 5 elementos.

Este patrón está directamente relacionado con el sistema de caché que construí más tarde. Las URLs firmadas de Supabase que expiran después de 60 minutos hacen que la precarga sea aún más crítica: las URLs deben estar frescas cuando el usuario desliza.

¿Por qué son tan importantes las microinteracciones?

Estas tres características — captura de video, arrastrar y soltar, carrusel — son invisibles individualmente. Nadie descarga una aplicación por su función de arrastrar y soltar pestañas. Pero colectivamente, crean una sensación de fluidez que marca toda la diferencia.

Los estudios de UX de Nielsen Norman Group muestran que la percepción de calidad de una aplicación está más influenciada por las microinteracciones que por las características principales. Un tiempo de respuesta de 100ms se percibe como instantáneo. Más allá de 300ms, el usuario comienza a sentir un retraso.

Esta es exactamente la filosofía que seguí para el botón de IA animado: cada interacción debe sentirse "viva". La animación del botón de grabación de video, la retroalimentación háptica al arrastrar y soltar, el ajuste magnético del carrusel, todo contribuye a esta sensación.

Medí el impacto de estos cambios con las analíticas de Firebase. El tiempo promedio pasado en la aplicación aumentó después del despliegue de estas características. No porque agreguen funcionalidades, sino porque hacen que el uso sea más agradable. Los usuarios permanecen más tiempo cuando la aplicación es fluida.

¿Qué herramientas usar para animaciones fluidas en React Native?

Para obtener animaciones a 60fps en dispositivos móviles, no puedes usar la API Animated básica de React Native. Todo debe pasar por el hilo de la interfaz de usuario nativa, no por el hilo de JavaScript. Aquí está la pila que uso:

  • react-native-reanimated: las animaciones se ejecutan en el hilo nativo, sin interrupciones
  • react-native-gesture-handler: gestión de gestos directamente en el hilo nativo
  • LayoutAnimation: para transiciones de diseño simples (agregar/eliminar elementos)

La combinación reanimated + gesture-handler se ha convertido en el estándar de facto para las animaciones de React Native en 2026. Si aún no las usas, migra. La diferencia de fluidez es inmediata y masiva.

He detallado el uso de esta pila en el artículo sobre la búsqueda contextual con deslizamiento, donde el gesto de deslizar hacia atrás para cerrar las pantallas de detalles utiliza exactamente el mismo patrón.

Lo que estos detalles me enseñaron sobre el desarrollo móvil

Estas dos semanas de trabajo en los "detalles" fueron de las más satisfactorias del proyecto. No porque las características sean impresionantes — no lo son — sino porque tienen un impacto desproporcionado en la experiencia del usuario.

Es una lección que aprendí por las malas: como desarrollador individual, la tentación es siempre ir tras la próxima gran característica. Pero los usuarios no ven las características. Ellos sienten la experiencia. Y la experiencia es la suma de cientos de microdecisiones: el retraso de una animación, el tamaño de un área táctil, la retroalimentación de un gesto.

Esto se une a lo que explico en el artículo sobre el onboarding: la primera impresión es crucial, y se juega en estos detalles. Un onboarding fluido con animaciones cuidadas da confianza. Un onboarding entrecortado con transiciones bruscas da ganas de desinstalar.

Preguntas frecuentes

¿Por qué limitar la duración de los videos a 60 segundos?

Para mantener los archivos ligeros y el almacenamiento viable. A 2 Mbps en 720p, 60 segundos representan aproximadamente 8 MB. Más allá de eso, los tiempos de carga y los costos de almacenamiento se vuelven problemáticos para una aplicación de productividad que no está centrada en el video.

¿El arrastrar y soltar de las pestañas funciona en iOS?

Sí. La implementación utiliza react-native-gesture-handler y react-native-reanimated, que son multiplataforma. El mismo código funciona en Android e iOS sin modificaciones. Solo los ajustes de retroalimentación háptica son específicos de cada plataforma.

¿El carrusel infinito no consume demasiada memoria?

No, gracias al sistema de reciclaje. Solo se mantienen 5 elementos en memoria (el elemento actual + 2 a cada lado). Los elementos más lejanos se liberan. En dispositivos con poca RAM, la ventana se puede reducir a 3 elementos.

¿Se puede desactivar la personalización de las pestañas?

El orden predeterminado se puede restaurar en cualquier momento a través de la configuración de la aplicación. Un botón "Restablecer" devuelve el orden original. El orden personalizado también se elimina si el usuario cierra sesión.

¿Por qué no usar Lottie para las animaciones?

Lottie es excelente para animaciones ilustrativas (iconos animados, pantallas de inicio) pero no es adecuado para animaciones interactivas impulsadas por gestos. react-native-reanimated permite vincular directamente el gesto a la animación, fotograma a fotograma, lo que Lottie no puede hacer.