Mi segunda APP para Android

13 de Noviembre del 2016


Hola, después de mi primera APP vuelvo con la segunda en la que incorporo más conceptos a entender por lo que recomiendo dar un vistazo al primer post para seguir el hilo de los conceptos.

Igual que la anterior podéis verla desde mi repositorio de GitHub.


android

Conceptos a entender antes de nada

Repasito rápido de conceptos para entender la APP.

Fragments

Con la llegada de pantallas más grandes (sobre todo para las tablets) era difícil adaptar la interfaz para éstas así que como solución nacieron los Fragments, podemos entenderlos como un contenedor de vistas que se nos mostrará en una porción de la interfaz aunque también puede ocupar toda, más adelante en la explicación de la aplicación se entenderá mejor este concepto viendo un par de fotos de cómo se ve en móvil y tablet.

Interfaz

Las interfaces las podemos definir como un conjunto de métodos que tienen que implementarse cuando utilizamos implements en una clase. Se define qué métodos va a contener pero no su funcionamiento, por lo que el desarrollador que los implemente tiene que definir la lógica de éstos.

Callbacks

Los callbacks son los métodos que definimos para pasar información entre clases. En esta práctica implementaremos una interfaz en las activities con unos métodos que hemos definido nosotros en cada Fragment para poder compartir datos.

Método onSaveInstanceState()

Este método lo podemos utilizar para guardar el estado de una aplicación, por ejemplo para recuperar los datos cuando giremos el dispositivo, ya que cada vez que giramos el dispositivo todo se vuelve a inflar, estos datos los podemos recuperar desde el Bundle que tienen como parámetro los métodos onCreate() y onCreateView().

Explicación de la práctica

mainactivity secondactivity

Esta aplicación tendrá dos tipos de vista según se abra desde un móvil o una tablet (gracias a los fragments) y además un tipo de vista diferente según si el dispositivo está en portrait o landscape como puede apreciarse en la imagen de arriba para su versión móvil, para versión tablet tenemos la imagen justo aquí debajo.

tablet

Una vez vistas las diferencias entre el móvil y tablet podemos apreciar para qué pueden servir los fragments, cuando lo ejecutamos en un móvil necesitamos una actividad que aloje cada uno de ellos mientras que en la tablet podemos decirle que la primera actividad contenga a los dos para aprovechar mejor el extra de tamaño en la pantalla.

La función de esta prática es averiguar cómo podemos enviar y recibir datos entre fragmentos pasando por las actividades:

  • Para móvil el recorrido es: fragmento del menú -> actividad principal -> actividad secundaria -> fragmento que pide dato.
  • Para tablet es: fragmento del menú -> actividad principal -> fragmento que pide dato.

Cómo podemos hacer esto

En este post en vez de ir poniendo trozos de código explicando que hace cada uno me enfocaré en los cambios más significativos con respecto al de mi primera APP ya que la gran mayoría de cosas están explicadas allí.

Guardar estado

save

Para poder guardar el estado de la aplicación hemos de sobrescribir el método onSaveInstanceState() indicando qué queremos que guarde, pondré como ejemplo el método que nos guarda el nombre que hemos introducido, el cual recupera el valor que tenemos en el TextView, en este caso Nombre: hola. Este método lo tenemos en la clase que contiene el Fragment.

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    savedInstanceState.putString(ActivityMain.KEY_ETIQUETA, tvDatos.getText().toString());

    super.onSaveInstanceState(savedInstanceState);
}

Para poder recuperarlo hemos de indicarlo desde el método onCreateView() con estas simples líneas.

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saveInstanceState) {
       View v = inflater.inflate(R.layout.fragmento_menu, container, false);

       // código del método

       // si se ha guardado algún valor cuando se giro la pantalla lo recuperamos
        if(saveInstanceState != null) {
            tvDatos.setText(saveInstanceState.getString(ActivityMain.KEY_ETIQUETA));
        }
}

Interfaces

Para poder enviar los datos hemos definido qué métodos se implementarán con las interfaces en el fragmento del menú por ejemplo:

public interface FragmentoMenuListener {
    void onPideNombre();
    void onPideEdad();
    void onPideTelefono();
}

Cuando desde la actividad principal implementemos la interfaz del fragmento con implements FragmentoMenu.FragmentoMenuListener tendremos que implementar esos métodos, como ejemplo tenemos el método que pone el nombre.

// llama a la segunda actividad si pulsamos el botón "PEDIR NOMBRE"
@Override
public void onPideNombre() {

    // si es tablet llamamos al método que pone el nombre de la etiqueta y ademas activamos
    // botón y el EditText (están desactivados por defecto)
    if(isTablet) {
        fragmentoDetalle.ponEtiqueta(DESDE_NOMBRE);
        fragmentoDetalle.setEnabled(true);

    // si no es tablet mandamos los datos a la segunda actividad
    } else {
        startActivityForResult(getIntentToActivitySecond(DESDE_NOMBRE), REQUEST_CODE);
    }
}

Cuando definimos la interfaz hemos de crear un método que nos defina un listener, para ello creamos una variable:

private FragmentoMenuListener escuchador;

Y luego con otro método seteamos el listener para que pueda ser utilizado:

public void setFragmentoMenuListener(FragmentoMenuListener escuchador) {
    this.escuchador = escuchador;
}

Para que por ejemplo al apretar uno de los botones podamos comunicarnos con los métodos que piden los datos desde la primera actividad, por ejemplo el onPideNombre() nombrado anteriormente.

@Override
public void onClick(View view) {
    if(botonNombre.getId() == view.getId())
        escuchador.onPideNombre();

    if(botonEdad.getId() == view.getId())
        escuchador.onPideEdad();

    if(botonTelefono.getId() == view.getId())
        escuchador.onPideTelefono();
}

Antes de terminar os dejo una imagen de cómo funciona la aplicación desde una tablet en la que podemos apreciar el envío de datos y cómo guarda los estados.

tablet

Todos estos conceptos pueden parecer caóticos pero una vez los has puesto en práctica se entienden mejor, pero si tienes alguna duda de cómo funcionan te recomiendo que te pases por mi repositorio de GitHub en el que está comentado todo el código parte por parte para que puedas entenderlo de una forma más cómoda, y si todavía te queda alguna duda no tengas problema en escribir a mi correo iam@jmoral.es o a mi Twitter @owniz.

Un saludo. ツ

Comparte en →