Navegando en nuestra aplicación Android

Buenas, la entrada de esta semana, es de esas sencillas pero bastante prácticas. Hoy veremos como navegar entre diferentes activitys.
Normalmente, una aplicación cualquiera suele tener más de una pantalla, bien porque añadimos una pantalla de configuración, porque tenemos una lista y un detalle, o un menú enlazado a sus diferentes pantallas.



Lo primero que vamos a hacer es crear un nuevo proyecto, yo le he llamado Navigation, y mi activity de inicio se llamará NavigationActivity. Y ahora crearemos dos activitys más, una de ellas le llamaremos NavigationDetail y la otra NavigationResult, para hacer esto basta ir a crear una clase nueva y hacer que herede de Activity.


También hemos de crear dos nuevos layouts para estas activitys, para ello en la carpeta layout hacemos botón derecho y creamos un nuevo archivo, yo les llamaré navigationdetail.xml y navigationresult.xml. El contenido inicial lo podemos copiar del layout main.xml que ha creado al hacer el proyecto.
el código que hemos de añadir en un principio para nuestras activitys es muy sencillo, simplemente debemos decirle cual es el layout que debe llamar, poniendo navigationdetail o navigationresult según sea el caso.


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.navigationdetail);
    }


Por último, debemos decirle a nuestra aplicación que tenemos estas dos nuevas pantallas de nuestra aplicación, para ello abrimos el archivo AndroidManifest.xml, en la vista de código debéis localizar el tag <application>, dentro de este es donde se declaran todas las activitys de nuestra aplicación. Como veis, por defecto ya está declarada nuestra activity principal, la cual además tiene un par de tags que indican que será la activity que se lanzará en el inicio de la aplicación. Si quisierais cambiar vuestro activity principal, simplemente deberéis llevaros estos tags a la activity principal.

Para declarar una nueva activity es muy sencillo, dentro del tag <application> definis un nuevo tag <activity>, que en nuestro caso quedaría de la siguiente forma:


<activity android:name=".NavigationDetail" />
<activity android:name=".NavigationResult" />


Una vez hecho esto nos falta navegar de una pantalla a otra. Para ello vamos a hacer una clase que nos ayude a centralizar las llamadas de navegación que llamaremos NavigationManager. En principio va a tener el siguiente código:


public static void navegarAActivityPrincipal(Activity activity){
  activity.finish();
  Intent itemintent = new Intent(activity, NavigationActivity.class);
  activity.startActivity(itemintent);
 }
 
 public static void navegarAActivityDetail(Activity activity, int id1, int id2){
  activity.finish();    
  Intent itemintent = new Intent(activity, NavigationDetail.class);
  Bundle b = new Bundle();
  b.putInt("id1", id1);
  b.putInt("id2", id2);
  itemintent.putExtra("android.intent.extra.INTENT", b);
  activity.startActivity(itemintent);
 }
 
 public static int getId1(Activity activity){
  int id1 = 0;
  Intent startingIntent = activity.getIntent();
        if (startingIntent != null)
        {
         Bundle b = startingIntent.getBundleExtra("android.intent.extra.INTENT");
         if (b != null) {
          id1 = b.getInt("id1");          
         }
        }
        return id1;
 }
 
 public static int getId2(Activity activity){
  int id2 = 0;
  Intent startingIntent = activity.getIntent();
        if (startingIntent != null)
        {
         Bundle b = startingIntent.getBundleExtra("android.intent.extra.INTENT");
         if (b != null) {
          id2 = b.getInt("id2");          
         }
        }
        return id2;
 }

 private final static int KEY_RESULT = 89865; 
 
 public static void navegarAActivityResult(Activity activity){
  Intent itemintent = new Intent(activity, NavigationResult.class);
  activity.startActivityForResult(itemintent, KEY_RESULT);
 }
 
 public static void returnValueActivityResult(Activity activity, int id1){
  Bundle bundle = new Bundle();
     bundle.putInt("id1", id1);
     Intent mIntent = new Intent();
     mIntent.putExtras(bundle);
     activity.setResult(Activity.RESULT_OK, mIntent);
     activity.finish();
 }
 
 public static int getValueActivityResult(int requestCode, int resultCode, Intent data){
  int id1 = 0;
  if(data != null && requestCode == KEY_RESULT && Activity.RESULT_OK == resultCode){
   id1 = data.getExtras().getInt("id1");  
  }  
  return id1;
 }
 
Tiene bastantes métodos pero yo prefiero tenerlos todos en el mismo punto para tener un mejor control de la navegación. Todos los métodos son estáticos para que no haga falta instanciar esta clase.


El primer método navegarAActivityPrincipal nos lleva a la activity de inicio. En todos los métodos para navegar definimos un objeto Intent que es una clase que nos permite una activity a ejecutar. En este caso le decimos que es la principal y después llamamos al método startActivity pasándole como parámetro el intent. Lo podemos utilizar así en un Button en nuestra activity NavigationDetail:


btn.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
           NavigationManager.navegarAActivityPrincipal(NavigationDetail.this);
      }
});


El segundo método, navegarAActivityDetail, hace casi lo mismo que es el anterior, pero ahora queremos pasarle una serie de parámetros a nuestra activity, para ello nos ayudamos de la calse Bundle a la que le vamos indicando todos los parámetros que enviaremos, y este Bundle se lo añadimos a nuestro Intent para que se lo envíe a la activity que vamos a abrir.


Para recoger estos parámetros utilizaremos los métodos getId1 y getId2, cada uno de estos revisan en el Intent de destino los BundleExtra que indicamos en el método anterior y buscar nuestros parámetros para devolverlos finalmente. Estos dos métodos debemos utilizarlos en el OnCreate del activity NavigationDetail. Para comprobar que funcionan podéis crear un TextView y mostrar los valores que habéis pasado desde otra activity.


@Override
public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.navigationdetail);
       
        int id1 = NavigationManager.getId1(this);
        int id2 = NavigationManager.getId2(this);
}


Los siguientes métodos se utilizan cuando desde una activity estamos realizando un proceso que por el medio necesita llamar a otra activity, desde esa nueva activity iniciamos un nuevo proceso que generará un resultado y se lo enviaremos a nuestra primera activity. Por ejemplo, seleccionar una foto o un contacto de nuestra agenda.


El método navegarAActivityResult, hace casi lo mismo que el resto, pero ahora llamamos a startActivityForResult y como segundo parámetro le pasamos una clave que hemos creado en esta misma clase con un código que elegimos nosotros. El cual nos servirá para recoger después el resultado.


El siguiente método, returnValueActivityResult, lo utilizaremos en el activity al que llamamos para devolver el resultado. Simplemente mete en el BundleExtra los valores que vamos a devolver y le decimos que el resultado de la operación ha sido correcto. Si quisierais controlar en la vuelta errores, etc.. podríais hacerlo con los distintos valores de RESULT.


Por último, una vez que hemos regresado a la activity de origen, debemos recoger estos parámetros, para ello debemos hacerlo en el método OnActivityResult, que es el encargado de recoger estas peticiones y procesarlas. Nosotros sobrescribiremos el método con el siguiente código:


@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      int id1 = NavigationManager.getValueActivityResult(requestCode, resultCode, data);
}


Con estos pocos casos podeis controlar la mayor parte de la navegación de una aplicación. Por último deciros que es en la clase NavigationManager donde deberiais añadir las llamadas para registrar como navegan los usuarios por vuestra aplicación. Si os acordáis vimos como hacerlo la semana pasada con Google Analitycs.

Comments are closed.