X

Crear una Interfaz de Usuario Flexible

Cuando estés diseñando tu aplicación para dar soporte a un amplio rango de tamaños de pantalla, puedes reutilizar tus fragmentos en configuraciones de layouts diferentes para optimizar la experiencia de usuario ya que se basan en el espacio de pantalla disponible.

Por ejemplo, en un móvil, puede ser apropiado mostrar únicamente un fragmento al mismo tiempo en una interfaz de usuario de un solo panel. Por otro lado, puedes mostrar varios fragmentos al mismo tiempo en una tablet ya que tiene un tamaño de pantalla mayor por lo que permite mostrar más información al usuario.

La clase FragmentManager proporciona los métodos que te permiten añadir, eliminar, y reemplazar los fragmentos de una actividad en tiempo de ejecución para poder crear una experiencia dinámica.

Figura 1. Dos fragmentos, mostrados en configuraciones diferentes para la misma actividad en diferentes tamaños de pantalla. En una pantalla grande, ambos fragmentos se muestran simultáneamente. Sin embargo, en un móvil solo se muestra un único fragmento el cual será reemplazado por el segundo cuando el usuario presione sobre un elemento.

Añadir un Fragment a una Actividad en Tiempo de Ejecución

En vez de definir el fragmento para una actividad en el archivo del layout, como se mostró en la lección anterior con el elemento <fragment>, también puedes añadir un fragmento a la actividad durante el tiempo de ejecución de la misma. Te será necesario si planeas cambiar los fragmentos durante la vida de la actividad.

Para realizar una transacción, añadir o eliminar un fragmento, debes utilizar FragmentManager para crear una FragmentTransaction, la cual proporciona las APIs para añadir, eliminar, reemplazar y realizar cualquier otra transacción de fragmentos.

Si tu actividad permite que los fragmentos sean eliminados y reemplazados, deberías añadir uno o varios fragmentos iniciales al método onCreate() de la actividad.

Una regla importante cuando estés utilizando los fragmentos, especialmente cuando estás añadiendo fragmentos en tiempo de ejecución, es que tu layout de la actividad debe incluir un contenedor View en el cual puedes insertar el fragmento.

El siguiente layout es una alternativa al layout mostrado en la lección anterior la cual muestra un único fragmento al mismo tiempo. Para reemplazar un fragmento con otro, el layout de la actividad incluye un FrameLayout vació que actúa como contenedor del fragmento.

Fíjate que el nombre del archivo es el mismo que el archivo del layout en la lección anterior, pero el directorio del layout no tiene el calificador large, así que este layout se utiliza cuando el tamaño de la pantalla es menor ya que la pantalla no puede mostrar los dos fragmentos al mismo tiempo.

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Dentro de tu actividad, llama a getSupportFragmentManager() para utilizar el FragmentManager gracias a las APIs de la Support Library. Después llama a beginTransaction() para crear una FragmentTransaction y poder llamar a add() para añadir un fragmento.

Puedes realizar varias transacciones de fragmentos para la actividad utilizando la misma FragmentTransaction. Cuando estés listo para realizar los cambios, debes llamar a commit().

Por ejemplo, observa cómo puedes añadir un fragmento al layout anterior:

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;

public class MainActivity extends FragmentActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.news_articles);

        // Check that the activity is using the layout version with
        // the fragment_container FrameLayout
        if (findViewById(R.id.fragment_container) != null) {

            // However, if we're being restored from a previous state,
            // then we don't need to do anything and should return or else
            // we could end up with overlapping fragments.
            if (savedInstanceState != null) {
                return;
            }

            // Create a new Fragment to be placed in the activity layout
            HeadlinesFragment firstFragment = new HeadlinesFragment();

            // In case this activity was started with special instructions from an
            // Intent, pass the Intent's extras to the fragment as arguments
            firstFragment.setArguments(getIntent().getExtras());

            // Add the fragment to the 'fragment_container' FrameLayout
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.fragment_container, firstFragment).commit();
        }
    }
}

Ya que el fragmento se ha añadido al contenedor FrameLayout en tiempo de ejecución, en lugar de definir el fragmento en el layout de la actividad con un elemento <fragment>, la actividad puede eliminar el fragmento y reemplazarlo con otro diferente.

Reemplazar un Fragment con Otro

El procedimiento para reemplazar un fragmento es similar al de añadir uno, la diferencia es que requiere utilizar el método replace() en lugar de add().

Ten en cuenta que cuando realices las transacciones de fragmentos, ya sea reemplazar o eliminarlos, a menudo es apropiado permitir al usuario que pueda volver atrás mediante el cambio “deshacer”. Para permitir al usuario que deshaga la transacción de fragmentos, debes llamar a addToBackStack() antes de utilizar commit() con la FragmentTransaction.

Nota: Cuando elimines o reemplaces un fragmento y añadas la transacción a la pila atrás, el fragmento que se ha eliminado se detiene (stopped), es decir, no es destruido (destroyed). Si el usuario navega hacia atrás y restaura el fragmento, este se reinicia. Si no añades la transacción a la pila atrás, el fragmento se destruye cuando sea eliminado o reemplazado.

 

Un ejemplo de un reemplazo de un fragmento con otro:

// Create fragment and give it an argument specifying the article it should show
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args);

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);

// Commit the transaction
transaction.commit();

El método addToBackStack() toma un parámetro string opcional que especifica un nombre único para la transacción. El nombre no es necesario a menos que planees realizar operaciones avanzadas de fragmentos utilizando las APIs FragmentManager.BackStackEntry.

Puedes ver más información sobre Crear una Interfaz de Usuario Flexible en la página oficial de Google en inglés pulsando aquí.

Los comentarios de Disqus están cargando....