Dilema: cuándo usar Fragmentos vs Actividades:

786

Sé que Activitiesestán diseñados para representar una sola pantalla de mi aplicación, mientras que Fragmentsestán diseñados para ser diseños de IU reutilizables con lógica incrustada dentro de ellos.

Hasta hace poco, desarrollé una aplicación que decía que deberían desarrollarse. Creé un Activitypara representar una pantalla de mi aplicación y utilicé Fragments para ViewPagero Google Maps. Raramente creé una ListFragmentu otra interfaz de usuario que se pueda reutilizar varias veces.

Recientemente me topé con un proyecto que contiene solo 2, Activitiesuno es a SettingsActivityy otro es el MainActivity. El diseño de la MainActivityse rellena con muchos fragmentos de IU de pantalla completa ocultos y solo se muestra uno. En la Activitylógica hay muchas FragmentTransitionsentre las diferentes pantallas de la aplicación.

Lo que me gustó de este enfoque es que debido a que la aplicación usa un ActionBar, permanece intacta y no se mueve con la animación de cambio de pantalla, que es lo que sucede con el Activitycambio. Esto le da una sensación más fluida a esas transiciones de pantalla.

Así que supongo que lo que pido es compartir su manera actual de desarrollo con respecto a este tema, sé que podría parecer una pregunta basada en la opinión a primera vista, pero lo veo como una pregunta de diseño y arquitectura de Android ... opinión basada en uno.

ACTUALIZACIÓN (01.05.2014): después de esta presentación de Eric Burke de Square , (lo que tengo que decir es una gran presentación con muchas herramientas útiles para desarrolladores de Android. Y no estoy relacionado de ninguna manera con Square)

http://www.infoq.com/presentations/Android-Design/

Desde mi experiencia personal durante los últimos meses, descubrí que la mejor manera de construir mis aplicaciones es crear grupos de fragmentos que representen un flujo en la aplicación y presenten todos esos fragmentos en uno Activity. Entonces, básicamente, tendrá el mismo número de Activitiesaplicaciones que el número de flujos. De esa manera, la barra de acción permanece intacta en todas las pantallas del flujo, pero se recrea al cambiar un flujo que tiene mucho sentido. Como Eric Burke afirma y como también me he dado cuenta, la filosofía de usar la menor cantidad Activitiesposible no es aplicable para todas las situaciones porque crea un desastre en lo que él llama la actividad "Dios".

Emil Adz
fuente

Respuestas:

271

Los expertos le dirán: "Cuando vea la interfaz de usuario, sabré si usar una Activityo una Fragment". Al principio esto no tendrá ningún sentido, pero con el tiempo, podrá saber si lo necesita Fragmento no.

Hay una buena práctica que me pareció muy útil. Se me ocurrió mientras intentaba explicarle algo a mi hija.

A saber, imagine una caja que representa una pantalla. ¿Puedes cargar otra pantalla en este cuadro? Si usa una nueva casilla, ¿tendrá que copiar varios elementos de la primera casilla? Si la respuesta es Sí, entonces debe usar Fragments, porque la raíz Activitypuede contener todos los elementos duplicados para ahorrar tiempo al crearlos, y simplemente puede reemplazar partes de la caja.

Pero no olvide que siempre necesita un contenedor de caja ( Activity) o sus partes se dispersarán. Entonces una caja con partes adentro.

Tenga cuidado de no usar mal la caja. Los expertos de Android UX aconsejan (puede encontrarlos en YouTube) cuándo debemos cargar explícitamente otro Activity, en lugar de usar un Fragment(como cuando tratamos con el cajón de navegación que tiene categorías). Una vez que te sientas cómodo Fragments, puedes ver todos sus videos. Aún más son material obligatorio.

¿Puedes ahora mirar tu interfaz de usuario y averiguar si necesitas una Activityo una Fragment? ¿Obtuviste una nueva perspectiva? Creo que lo hiciste.

sandalone
fuente
44
¿tienes un enlace al feed de youtube que mencionaste? Busco "expertos en Android UX" y "Android UX", pero no estoy completamente seguro de qué videos estás hablando.
yo--
2
Ya no más, lo vi hace más de un año. Buscar oficial de desarrollador de Android hablando sobre UX
sandalone
1
Un ejemplo de consideración: la actividad tiene parentActivity para que podamos sintetizar backstack al ingresar desde la notificación, pero no creo que exista ese parentFragment.
fikr4n
@BornToCode hay getParentFragment: developer.android.com/reference/android/support/v4/app/…
ToolmakerSteve
@ToolmakerSteve sí, es getParentFragment, pero no es lo que quise decir amigo, vea developer.android.com/guide/topics/manifest/…
fikr4n
129

Mi filosofía es esta:

Cree una actividad solo si es absolutamente necesaria. Con la pila posterior disponible para confirmar un montón de transacciones fragmentarias, intento crear la menor cantidad de actividades posible en mi aplicación. Además, la comunicación entre varios fragmentos es mucho más fácil que enviar datos entre las actividades.

Las transiciones de actividad son caras, ¿verdad? Al menos eso creo, ya que la antigua actividad tiene que ser destruida / pausada / detenida, empujada a la pila, y luego la nueva actividad tiene que ser creada / iniciada / reanudada.

Es solo mi filosofía desde que se introdujeron los fragmentos.

VJ Vélan Solutions
fuente
2
cierto, pero como has escrito, a veces es necesario usar actividades. Un ejemplo es la pantalla de una cámara, donde es mejor usarla en modo horizontal. otro ejemplo es la pantalla de configuración que se muestra cuando coloca un widget de aplicación personalizado (en el "escritorio" - la aplicación de inicio).
Desarrollador de Android el
Gracias por responder y compartir su experiencia. ¿Cree que es una buena práctica en Android limitar la aplicación a una Actividad y usar Fragmento para toda la pantalla si la arquitectura de la aplicación lo permite?
Emil Adz
1
Entonces, ¿cómo se resuelve el problema de los fragmentos que necesitan pasar entre sí "estado"? Todo el estado en todos sus fragmentos necesita vivir en la única actividad, de lo contrario, se ve obligado a usar un singleton.
Mr_E
36
No estoy convencido de que la comunicación entre varios fragmentos sea mucho más fácil en lugar de enviar datos de un lado a otro entre actividades.
Denny
3
Al menos, onActivityResult()es más seguro y más fácil que las devoluciones de llamada de fragmentos.
CoolMind
59

Bueno, de acuerdo con las conferencias de Google (tal vez aquí , no lo recuerdo), deberías considerar usar Fragments siempre que sea posible, ya que hace que tu código sea más fácil de mantener y controlar.

Sin embargo, creo que en algunos casos puede volverse demasiado complejo, ya que la actividad que alberga los fragmentos necesita navegar / comunicarse entre ellos.

Creo que deberías decidir por ti mismo qué es lo mejor para ti. Por lo general, no es tan difícil convertir una actividad en un fragmento y viceversa.

He creado una publicación sobre este dillema aquí , si desea leer más.

desarrollador de Android
fuente
55
Gracias por responder y compartir su experiencia. ¿Cree que es una buena práctica en Android limitar la aplicación a una Actividad y usar Fragmento para toda la pantalla si la arquitectura de la aplicación lo permite?
Emil Adz
Depende del proyecto, pero si se vuelve demasiado complicado para usted, también puede separarse para múltiples actividades. No tengas miedo de usar ninguno de los métodos. También puedes usarlos a ambos. Tal vez a veces le resulte demasiado difícil utilizar fragmentos en lugar de actividades. Creo que debería intentar usar fragmentos, pero no lo obligue a estar en todas partes si se interpone demasiado en su camino ...
Desarrollador de Android
¿Qué sucede si quiero mantener este efecto de la barra de acciones intacta y se cambia todo el contenido? ¿Es posible lograr esto con Actividades?
Emil Adz
27

Por qué prefiero Fragmento a Actividad en TODOS LOS CASOS.

  • La actividad es cara. En Fragment, las vistas y los estados de propiedad están separados: cada vez que se encuentre un fragmento backstack, sus vistas se destruirán. Entonces puedes apilar muchos más fragmentos que actividad.

  • Backstackmanipulación. Con FragmentManager, es fácil borrar todos los Fragmentos, insertar más que en Fragmentos y etc. Pero para Activity, será una pesadilla manipular esas cosas.

  • Un ciclo de vida mucho más predecible . Siempre que la Actividad del host no se recicle. Los fragmentos en el backstack no serán reciclados. Por lo tanto, es posible utilizar FragmentManager::getFragments()para encontrar un fragmento específico (no recomendado).

Qylin
fuente
Hola, leí tu comentario sobre las ventajas de Frag sobre Act, ¿tienes algún proyecto para mostrar lo mismo en tu repositorio de Github?
Ümañg ßürmån
24

Desde Jetpack , la aplicación Single-Activity es la arquitectura preferida. Útil especialmente con el componente de arquitectura de navegación .

fuente

Francis
fuente
¡Gracias por esto!
Simão Garcia el
1
Hoy leí sobre Jetpack por primera vez. :) Creamos aplicaciones de actividad única desde que se introdujeron fragmentos. La actividad múltiple es mucho más complicada.
El increíble Jan
1
@TheincredibleJan Tienes razón, la arquitectura de la aplicación Single Activity era una solución mejor mucho antes de Jetpack
Francis
12

En mi opinión, no es realmente relevante. El factor clave a considerar es

  1. ¿Con qué frecuencia vas a reutilizar partes de la interfaz de usuario (menús, por ejemplo),
  2. ¿La aplicación también es para tabletas?

El uso principal de los fragmentos es crear actividades multipane, lo que lo hace perfecto para aplicaciones sensibles a tabletas / teléfonos.

Isaac Urbina
fuente
Diría que el uso principal de los fragmentos es crear vistas personalizadas sin pensar en ellas como vistas personalizadas. Eso es lo que sucede de todos modos. Fragmentos que Google nos mostró originalmente como una forma práctica de crear aplicaciones que respondan a las tabletas, por lo que puede pegarlas en diferentes actividades si lo desea. una forma de adjuntar código a una vista, más o menos, y tenerlos pegados donde desee (sin hacer vistas personalizadas).
Lassi Kinnunen
11

¡No olvide que una actividad es el bloque / componente de la aplicación que se puede compartir e iniciar a través de Intent! Por lo tanto, cada actividad en su aplicación debe resolver solo un tipo de tarea. Si solo tiene una tarea en su aplicación, creo que solo necesita una actividad y muchos fragmentos si es necesario. Por supuesto, puede reutilizar fragmentos en actividades futuras que resuelvan otras tareas. Este enfoque será una separación clara y lógica de las tareas. Y no es necesario mantener una actividad con diferentes parámetros de filtro de intención para diferentes conjuntos de fragmentos. Usted define tareas en la etapa de diseño del proceso de desarrollo en función de los requisitos.

invitado
fuente
En nuestras aplicaciones, el único tipo de tarea de la actividad es mantener el cajón de navegación para ingresar los diferentes fragmentos. :) ¿Por qué debería lidiar con intentos de fragmentos? Es claro y lógico mantener una referencia estática a una clase de datos "global" para datos globales y pasar algunos valores a un método de creación de instancia de un fragmento.
El increíble Jan
9

Hay más en esto de lo que cree, debe recordar que una actividad que se inicia no destruye implícitamente la actividad de llamada. Claro, puede configurarlo de modo que su usuario haga clic en un botón para ir a una página, comience la actividad de esa página y destruya la actual. Esto causa mucha sobrecarga. La mejor guía que puedo darte es:

** Inicie una nueva actividad solo si tiene sentido tener la actividad principal y esta abierta al mismo tiempo (piense en varias ventanas).

Un gran ejemplo de cuándo tiene sentido tener múltiples actividades es Google Drive. La actividad principal proporciona un explorador de archivos. Cuando se abre un archivo, se inicia una nueva actividad para ver ese archivo. Puede presionar el botón de aplicaciones recientes que le permitirá volver al navegador sin cerrar el documento abierto, y quizás incluso abrir otro documento en paralelo al primero.

TheHebrewHammer
fuente
Re "Inicie una nueva actividad solo si tiene sentido tener la actividad principal y esta abierta al mismo tiempo (piense en varias ventanas)". No lo creo. Esa situación está bien resuelta utilizando fragmentos attach / detachmétodos.
ToolmakerSteve
7

Cosa que hice: usar menos fragmentos cuando sea posible. Desafortunadamente, es posible en casi todos los casos. Entonces, termino con muchos fragmentos y un poco de actividades. Algunos inconvenientes que me di cuenta:

  • ActionBar& Menú: cuando 2 fragmentos tienen un título, menú diferente, eso
    será difícil de manejar. Por ejemplo: al agregar un nuevo fragmento, puede cambiar el título de la barra de acción, pero al abrirlo desde backstackallí no hay forma de restaurar el título anterior. Es posible que necesite una barra de herramientas en cada fragmento para este caso, pero créame, eso le llevará más tiempo.
  • Cuando necesitamos startForResult, la actividad tiene pero el fragmento no.
  • No tiene animación de transición por defecto

Mi solución para esto es usar una Actividad para envolver un fragmento dentro. Entonces tenemos una barra de acción separada, menú startActivityForResult, animación, ...

Amo la codificación
fuente
1
Puntos muy útiles, gracias. ¿Puedes aclarar " una Actividad para envolver un fragmento "? ¿Hiciste una actividad separada para cada fragmento? Si es así, ¿necesitas Fragmento?
ToolmakerSteve
3
Hay una manera de restaurar el título y esas cosas. use getSupportFragmentManager().addOnBackStackChangedListenerpara agregar un oyente. obtener fragmento actual en ese oyente y luego establecer el título y esas cosas.
babay
4

La gran ventaja de una fragmentsobreactividad es que, el código que se usa para fragmentos puede usarse para diferentes actividades. Por lo tanto, proporciona la reutilización del código en el desarrollo de aplicaciones.

Sanchit Bhasin
fuente
3
¿Cómo? ¿Podría dar algún ejemplo por favor?
sofs1
1
@ sofs1 Tu pregunta no tiene mucho sentido. Cualquier código en un fragmento permanece igual sin importar de qué actividad se instale el fragmento.
El increíble Jan
@TheincredibleJan Pero, ¿no podríamos decir también "Cualquier código en una actividad sigue siendo el mismo sin importar de qué actividad se instancia la segunda actividad"? No veo la diferencia
iforce2d
3

use una actividad por aplicación para proporcionar una base para el fragment uso fragmentde la pantalla, fragmentstienen un peso reducido en comparación con los activites fragmentos, los fragmentos reutilizables son más adecuados para aplicaciones que admiten teléfonos y tabletas

varg
fuente
2

Eres libre de usar uno de esos.
Básicamente, debes evaluar cuál es el mejor para tu aplicación. Piense en cómo administrará el flujo de negocios y cómo almacenar / administrar las preferencias de datos.

Piense en cómo los Fragmentos almacenan datos basura. Cuando implementa el fragmento, tiene una raíz de actividad para llenar con fragmento (s). Entonces, si está tratando de implementar muchas actividades con demasiados fragmentos, debe considerar el rendimiento en su aplicación, porque está manipulando (habla groseramente) el ciclo de vida de dos contextos, recuerde la complejidad.

Recuerde: ¿debo usar fragmentos? ¿Por qué no debería?

Saludos.

Franklin Hirata
fuente
1

Utilizo Fragments para una mejor experiencia de usuario. Por ejemplo, si tiene un Botón y desea ejecutarlo, digamos un servicio web cuando hace clic en él, adjunto un Fragmento a la Actividad principal.

if (id == R.id.forecast) {

    ForecastFragment forecastFragment = new ForecastFragment();
    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();
    ft.replace(R.id.main_content, forecastFragment);
    ft.addToBackStack("backstack");
    forecastFragment.setArguments(b);
    ft.commit();
}

De esa manera, el usuario no tendrá que moverse en otra actividad.

Y en segundo lugar, prefiero Fragments porque puedes manejarlos fácilmente durante la rotación.

Theo
fuente
¿Qué hace que ese ejemplo sea una mejor experiencia de usuario? ¿Cómo sabrán (o les importará) que están haciendo una actividad o un fragmento?
iforce2d
1

Depende de lo que quieras construir realmente. Por ejemplo, navigation drawerutiliza fragmentos. Las pestañas también se usan fragments. Otra buena implementación, es donde tienes un listview. Cuando gira el teléfono y hace clic en una fila, la actividad se muestra en la mitad restante de la pantalla. Personalmente, lo uso fragmentsy fragment dialogs, como es más profesional. Además, se manejan más fácilmente en rotación.

Theo
fuente