2011-07-13 5 views
20

Considerar la aplicación de ejemplo de developers.android.comFragmentos: ¿tiene que usar un Contenedor de actividades alrededor de un fragmento que comprende toda la Actividad?

Esto describe el uso de fragmentos de este modo:

  • en un teléfono que puede utilizar Fragmento 1 de la Actividad A y el fragmento 2 de la actividad B.
  • en una tableta que tener más bienes raíces, por lo que utiliza el Fragmento 1 y el Fragmento 2 en la Actividad A.

¡Genial! ... Pero ... En el primer ejemplo (el que tiene un teléfono), usted crea una Actividad con un archivo xml que contiene un solo <fragment> y eso es todo, ¿en la actividad solo llama al setContentView() en ese xml? Parece mucho código redundante (Actividad, XML & Fragmento para mostrar un Fragmento): ¿Puede establecer Fragment como Activity o siempre se requiere un Contenedor con XML?

Respuesta

34

Ah, lo encontró here

public class MainMenuHolder extends FragmentActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     // If not already added to the Fragment manager add it. If you don't do this a new Fragment will be added every time this method is called (Such as on orientation change) 
     if(savedInstanceState == null) 
      getSupportFragmentManager().beginTransaction().add(android.R.id.content, new MainMenuFragment()).commit(); 
    } 
} 

FragmentActivity permite de establecer el Fragmento como el contenido de android.R.id.content que supongo que es el ID interno androide del tronco visión.

Con este método, usted todavía termina con una actividad mayormente redundante (si todo lo que quiere es que el Fragmento actúe como la Actividad). Pero aún así, la mitad de pelusa que tener una actividad y un archivo XML que actúa como un contenedor.

¡Cualquier otra respuesta sería apreciada!

+1

teniendo la solución un paso orientadas hacia crear genérica 'SingleFragmentActivity' que obtiene un fragmento como constructor param y lo agrega' onCreate'. luego usa esta actividad cada vez que necesites alguna actividad de fragmento único. – shem

+2

@shem: hago exactamente lo mismo: paso el nombre canónico de Fragment como acción para que pueda ser instanciado desde String. – Graeme

+0

Bueno, también puedes dejar de usar Fragmentos a menos que realmente necesites uno. En la mayoría de los casos, el uso de una actividad simple también haría bien el trabajo –

2

El ejemplo en línea no completa todos los espacios en blanco. Trataré de responder sus preguntas directamente:

"En el primer ejemplo (el que tiene un teléfono), debe crear una Actividad con un archivo xml que contenga una sola y una actividad que solo llame a setContentView() en ese xml ¿y eso es todo?"

Has comenzado en el lugar correcto. Pero hay más que eso. Siempre hay más de una forma de resolver un problema en Android, pero es una forma recomendada de generar el efecto de tener un número dinámico de fragmentos en función de la disponibilidad. bienes raíces es:

  1. crear archivos de diseño XML en/diseño para la primaria (por defecto) dirigida orientación/dispositivo/factor de forma/SDK
  2. Crear archivos XML de diseño para la línea de base más pequeña de ancho por otra dirigida dispositivos. Es posible que también desee orientar otras orientaciones, SDK, etc.
  3. Cada archivo XML de diseño tendrá su propio conjunto de fragmentos definidos
  4. En la actividad, verifique qué fragmentos están presentes.

Es evidente que se puede adoptar una estrategia análoga para los diseños programáticos.

En su ejemplo en la pregunta original (de documentos de Google) que podría tener:

  • diseño/principal.XML :: esta disposición sólo tendría Fragmento 1
  • diseño-sw600dp/main.xml :: esta disposición tendría fragmentos 1, 2

Luego, en MainActivity.java que sería comprobar la existencia de cada fragmento . Para hacer esto, podría usar FragmentManager # findFragmentById() para tener una comprobación como: si findFragmentById() devuelve nulo para Fragment-2, MainActivity sabe que el dispositivo tiene layout/main.xml cargado y solo admite un fragmento.

Dar un "paso atrás" del ejemplo revela algo que: antes de usar Fragmentos, podría haber llamado a la Actividad B de la Actividad A con startAcitityForResult (int). En el paradigma del Fragmento, probablemente solo necesites un resultado del Fragmento 2 para que ocurra algo en el Fragmento 1, por lo que es razonable que MainActivity sea el guardián de esa situación. A medida que expande el ejemplo, puede ver que en otras aplicaciones, MainActivity puede necesitar llamar a otras actividades, por cualquier razón. Tal vez esté apuntando a una tableta grande con suficiente espacio para 3 fragmentos, pero en un teléfono que debe ser de 3 actividades. Las cosas pueden ponerse interesantes, pero la Fragment API es bastante poderosa.

"¿Se puede establecer un Fragmento como una Actividad o siempre se requiere un Contenedor cuando se utilizan fragmentos?"

Un fragmento no es una actividad. De hecho, los Fragmentos están cargados por Actividades, por lo que uno podría decir que siempre se requiere un contenedor. Estás tocando otro aspecto sutil de Fragmentos. Mientras que las Actividades se comportan como Controladores MVC, los Fragmentos podrían llamarse "minicontroladores" debido a su ciclo de vida, que se asemeja y se ejecuta junto con una Actividad. De nuevo, el ciclo de vida del Fragmento está contenido dentro ("envuelto por") en el ciclo de vida de la Actividad que administra el Fragmento. Recomiendo familiarizarse con el ciclo de vida de Fragment documentado en http://developer.android.com/guide/topics/fundamentals/fragments.html#Lifecycle.

+10

No tengo idea de lo que está respondiendo aquí ...? – Graeme

1

Más genéricamente se podría crear una clase contenedora fragmento:

public class SingleFragmentActivity extends Activity { 

    public static final String FRAGMENT_NAME = "fragmentName"; 
    public static final String FRAGMENT_ARGUMENTS = "fragmentArguments"; 

    @Override 
    protected void onCreate(@Nullable Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     String fragmentName = getIntent().getStringExtra(FRAGMENT_NAME); 
     Fragment fragment = Fragment.instantiate(this, fragmentName); 
     Bundle fragmentArguments = getIntent().getBundleExtra(FRAGMENT_ARGUMENTS); 
     fragment.setArguments(fragmentArguments); 
     getSupportFragmentManager().beginTransaction().replace(android.R.id.content,fragment, "tag").commit(); 
    } 
} 

ahora se utiliza esta clase para crear instancias de cualquier fragmento como una actividad independiente:

public void showFragmentAsActivity() { 
    Intent intent = new Intent(this, SingleFragmentActivity.class); 
    intent.putExtra(SingleFragmentActivity.FRAGMENT_NAME, MyFragment.class.getName()); 
    intent.putExtra(SingleFragmentActivity.FRAGMENT_ARGUMENTS,MyFragment.getArgumentsBundle("a string argument")); 
    startActivity(intent); 
} 
Cuestiones relacionadas