28 comentarios el “Retornar valor desde una Actividad Secundaria en Android

  1. muy bueno me daba errores pero con este ejemplo ya me saliio
    solo tengo un a pregunta, si de la activity1 mando a llamar otras 3 activitys como puedo saber cual de todas es la qe esta finalizando para recibir los valores qe me regresa cada una de ellas??

    en este codigo como diferencio cual activity termina ???
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if ((requestCode == request_code) && (resultCode == RESULT_OK)){
    tvTexto.setText(data.getDataString());
    }
    }

    saludos y grasias

      • Recuerda que lo que usamos para comunicar las Activities son objetos de la clase Intent, por lo tanto podemos añadirle “extras”, ya sea con un objeto de la clase Bundle o mediante el método .putExtra(key, value). Es prácticamente igual que pasar parámetros de un lado a otro.

        Espero que te sea de ayuda.

        Saludos!!!

    • Buenas beto,

      Para poder hacer esto que me comentas, puedes hacer uso de requestCode, ¿Como?, con código se vé mejor :):

      public void onActivityResult(int requestCode, int resultCode, Intent intent){
          switch(requestCode){
              case REQUEST_CODE_1: // Hacemos cosas de una actividad aquí
              break;
              case REQUEST_CODE_2: // Hacemos cosas de otra actividad aquí
              break;
              case REQUEST_CODE_3: // Lo que tengamos
              break;
          }
      }
      

      Para esto, tus llamadas a las Activity deben ser de este tipo:

      startActivityForResult(intent, REQUEST_CODE_1);
      
      startActivityForResulr(intent, REQUEST_CODE_2);
      
      startActivityForResult(intent, REQUEST_CODE_3);
      

      Donde REQUEST_CODE_X puede ser un valor constante o algo que tengas por ahí, así sabrá la aplicación de donde viene el intent de regreso.

      Espero que te sea de ayuda.

      Saludos!!

  2. como podria hacer para agregar scroll a mi app ya qe cuando lleno los controles si estos se cambian de tamaño los de mas abajo se ven reducidos o desaparecen o tambien cuando aparece el teclado qe me permita hacer scroll para que desaparesca el teclado
    no se si tengas algun tutorial sobre esto
    grasias

    • Puedes encerrar todo ello en un ScrollView, aunque ten en cuenta que los ScrollView solo aceptan un hijo en su interior por lo que deberías encerrar el contenido en un LinearLayout o en algún otro tipo de contenedor. Te pongo un ejemplo:

      <ScrollView
          android:layout_width="fill_parent"
          android:layout_height="wrap_content" >
      
          <LinearLayout
              android:layout_width="fill_parent"
              android:layout_height="wrap_content" 
              android:orientation="vertical">
      
              <TextView>
              </TextView>
      
              <Button>
              </Button>
      
              <EditText>
              </EditText>
      
              <TextView>
              </TextView>
          </LinearLayout>
      
      </ScrollView>
      

      Espero que te sea de ayuda!.

      Saludos!!!

  3. hola el retornar un valor lo entendi es bueno tu aporte ,pero no entiendo o no se como hacer para devolver mas de un valor estoy empezando en esto tu crees que me podrias dar maS DETALLES

  4. Buenas noches gracias de ante mano por tu aporte una pregunta :¿como puedo devolver dos parametros de una lista en mi lista muestro nombre y categoria por item ? con tu aporte solo puedo devolver el nombre pero quiero devolver la categoria tambien .Gracias por tu respuesta

    • Buenas Jorge, perdona el retraso de mi contestación:

      Al fin y al cabo lo que retornamos es un Intent, en el cual podemos incluir mas información de manera muy fácil.

      intent.putExtra(ALGO, "variable");
      

      Si por otro lado quisieras retornar un objeto que hayas creado tu propio, este objeto deberia implementar la interface Parcelable, la cual permite pasar objetos en un intent.

      Espero haber sido de ayuda.

      Saludos!

      • Gracias ahora entendi ya me muestra los datos que queria excelente nuevamente gracias por tu ayuda

  5. Hola, tu ejemplo me es interesante, pero a ver como podria hacer lo siguiente, tego una actividad principal la cual tiene una lista con nombre y precios, y los precios los quiero actualizar, primera opcion que se me ocurrio fue crar una segunda actividad para pedir el importe, entonces tengo que, al presionar un item de la lista se tiene que actualizar el importe, esto lo tengo echo pero ahora necesito recoger el dato de la segunda actividad dentro del evento del click de la lista (no se si me e explicado bien). como puedo hacerlo?
    hay alguna forma de pedir este dato mas sencillamente?
    Saludos.
    Javier,,

    • Buenas javier,

      Por lo que me comentas, tienes 2 Activities, una para mostrar los nombres y los precios, y luego otra que se abre al pulsar un elemento de esta primera activity (No se si es exactamente como me lo has comentado).

      Por esta opción, puedes mandar la posición del elemento que has pulsado a la segunda activity, junto al precio o los datos que quieras, modificarlos en esta, y de nuevo al darle al click o tal como lo tengas montado, devolver esta serie de datos a la activity 1 metiendolo todo en un Intent, y analizando luego en el método onActivityResult los datos que vienen, y al actualizarlo en el adaptador de datos, llamar al método notifyDataSetChanged del Adapter para que los datos en el ListView se apliquen.

      Otra opción, puede ser que al pulsar un elemento, saques un DialogFragment (un dialog) con un campo de texto cargado con el precio antiguo, y dejar que se actualice ahí, de este modo te ahorras una pantalla.

      Cualquier opción es viable y puedes emplearla, ya que sigue las lineas de diseño de Android. Solo que si en un futuro necesitas editar mas información que no sea el precio, seguramente te sea mejor usar la primera opción, pero ya es como veas 😉

      Espero haberte sido de ayuda, cualquier pregunta no dudes en escribir

      Saludos!!

      • Hola.
        para recuperar la posicion ago lo siguiente:
        listView.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView pariente, View view, int posicion, long id) {
        EntradaLista elegido = (EntradaLista) pariente.getItemAtPosition(posicion);
        }
        });
        para pasar la posicion a la otra actividad como seria.
        luego al recibir denuevo la posicion en el onActivityResult, como ago para relacionar la posicion con la EtradaLIsta y poder modificar el valor?
        Saludos.
        Javier,,

  6. Hola, me a surgido otra duda.
    al hacer click en un item de la lista, y llamar otra actividad, cuando vuelvo a la principal, he perdido la lista, como devo hacer para no perder los items de la lista, gracias.

    Saludos.
    Javier,,

    • Buenas Javier,

      Te respondo a ambas aqui.

      Respecto a lo primero, para pasar la posición lo puedes hacer igual que si pasaras otra variable mas en el Intent, o puedes tener una variable de instancia en tu primera activity donde tengas el último elemento pulsado, lo cual esta segunda opción te lleva a la segunda respuesta.

      Esto te pasa porque no guardas el estado de la aplicación. Es el comportamiento de android por defecto, cuando pasas a una activity, la que dejas atrás puede ser destruida por el sistema para liberar memoria, lo que quiere decir que al volver, entrará de nuevo por el método onCreate. Si no has preparado la activity para guardar el estado que había con anterioridad, tendrás todo igual que cuando entraste. Decirte que esto te pasa tambien si cambias de orientación la aplicación.

      Puedes hacer una activity con un EditText, rellenar algo, y cambiar la orientación, observarás como lo que habia dentro ha desaparecido.

      Para guardar el estado de tus activities, puedes guiarte por este tutorial: https://sekthdroid.wordpress.com/2012/10/04/mantener-los-datos-cuando-rotemos-la-pantalla-en-android/ que hice hace tiempo pero sigue siendo igualmente válido.

      Saludos!!

  7. Hola. he intentado pasar la informacion de una pantalla a otra como me indicabas, pero hay algo que me falla, como aun no he conseguido que me guarde los datos al devolver el resultado agrego un componente en la posicion 0 del array que es el que utilizo para hacer la peticion, tengo lo siguiente:

    llamada de la actividad principal a la de introduccion de nuevo importe:

    listView.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView pariente, View view, int posicion, long id) {

    //EntradaLista elegido = (EntradaLista) pariente.getItemAtPosition(posicion);

    //Creamos el Intent y los datos a pasar
    Intent Informacion = new Intent(MainActivity.this, IntImporte.class);
    Bundle b = new Bundle();
    b.putInt(“POSICION”, posicion);
    Informacion.putExtras(b);

    //Iniciamos la nueva actividad
    startActivityForResult(Informacion, request_code);
    }
    });

    en la segunda actividad devuelvo la posicion y el nuevo importe

    final int posicion;

    //Recuperamos la información pasada en el intent
    Bundle bundle = this.getIntent().getExtras();
    posicion = bundle.getInt(“POSICION”);

    //Implementamos el evento “click” del botón
    btnSumar.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {

    //creamos el intent
    Intent DeVuelta = new Intent();

    //asignamos los valores a pasar
    Bundle b = new Bundle();
    b.putInt(“POSICION”, posicion);
    b.putString(“IMPORTE”, txtImporte.toString());

    DeVuelta.putExtras(b);

    setResult(RESULT_OK, DeVuelta);
    finish();
    }
    });

    y luego recibo la informacin y intento actualizar el item de la posicion seleccionada

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // TODO Auto-generated method stub
    if ((requestCode == request_code) && (resultCode == RESULT_OK)){

    int posicion;
    String importeDev;

    //Recuperamos la información pasada en el intent
    Bundle bundle = this.getIntent().getExtras();
    posicion = bundle.getInt(“POSICION”);
    importeDev = bundle.getString(“IMPORTE”);

    EntradaLista elegido = (EntradaLista) pariente.getItemAtPosition(0);

    String Valor1 = elegido.getImporte().toString();
    float nro1 = Float.parseFloat(Valor1);
    nro1 = nro1 + Float.parseFloat(importeDev);

    elegido.setImporte(String.valueOf(nro1));
    adapter.notifyDataSetChanged();

    }
    }
    creo que me falla el onActivityResult, creo que no esta bien ni la recuperacion de los valores ni la linea de EntradaLista (es una clase que junto a un adaptador gestionan la informacion de la lista, NOMBRE,IMPORTE), que me falla?

    lo curioso es que en otro ejemplo de mantener la info de esta activity, te e escrito por que no se que me falla a la hora de guardar el string, pero lo e quitado para intentar hacer esta parte mientras y cuando devuelvo los valores a la actividad principal siguen estando los items.

    he puesto en el androidmanifiest el comando android:configChanges=”keyboardHidden|orientation|screenSize”, y asi tambien se me mantiene al rotar la pantalla, o es preferible hacerlo como en tu ejemplo.

    Saludos,
    Javier,,

  8. Buenas Javier,

    Yo creo que tienes un buen lio ahi montado!! jejeje

    Lo primero que veo es que la linea

    EntradaLista elegido = (EntradaLista) pariente.getItemAtPosition(0); // posicion en vez de 0?

    Creo que deberías coger el elemento de la lista por la posición, no 0, y al editarlo, el adapter.notifyDataSetChanged() si debería realizar los cambios.

    Lo segundo, creo que en este bloque tienes un lio tremendo:

    String Valor1 = elegido.getImporte().toString();
    float nro1 = Float.parseFloat(Valor1);
    nro1 = nro1 + Float.parseFloat(importeDev);

    Lo que yo haría es lo siguiente:

    // Si es un precio o algo por el estilo, lo mejor sería, por simple definición de datos, tratarlo como un
    // float no?
    float returnValue = bundle.getFloat(“IMPORTE”);

    // Lo mismo, al ser un precio, y si has estudiado bien a la hora de modelar los datos, normalmente
    // los precios son tipos de dato fload o double
    elegido.setImporte(nro1 + returnValue);

    Con esto eliminarias muchas conversiones a String o Float para poder sumar o no valores, lo cual bueno, por poder se puede hacer, aunque con un buen modelo de datos bien definido (Nombres como String, precios como float o double, ids como long etc) te quitas muchos problemas, tu código será mas legible, y evidentemente será mejor, así que mejor estudia antes este tema para modelar bien tu clase y no guardar algo que en la realidad es un tipo de dato diferente al que vas a guardar (No me explico demasiado bien, pero con lo que puse arriba me entenderás xD)

    Respecto al tema de mantener los datos y no perderlos, yo siempre prefiero hacer uso de los métodos onSaveInstanceState y onCreate para controlar cuando mis datos son recuperados o no, te pongo un código de ejemplo de como lo haría en mi caso, lo cual, evidentemente, no tiene porque ser la mejor forma, ya que siempre hay opciones, pero así es como lo haría yo en tu caso:

    public class MainActivity extends Activity {
    private ListView mListView;
    private PreciosAdapter mAdapter;
    private ArrayList mList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mListView = (ListView)findViewById(R.id.listview);

    // Comprobamos si se recupera de un cambio de estado, o entra por primera vez
    if (savedInstanceState == null) {
    // Cargamos la lista desde donde sea
    mList = DataSource.getInstance(this).getEntradaLista();
    }else{
    // Recuperamos el estado anterior
    mList = savedInstanceState.getParcelableArrayList(“LISTA”);

    }

    mAdapter = new PreciosAdapter(this, mList);
    mListView.setAdapter(mAdapter);

    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    // Guardamos la lista, que es lo que nos interesa
    outState.putParcelableArrayList(“LISTA”, mList);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if ((requestCode == request_code) && (resultCode == RESULT_OK)){
    int posicion;
    String importeDev;

    //Recuperamos la información pasada en el intent
    Bundle bundle = this.getIntent().getExtras();
    posicion = bundle.getInt(“POSICION”);
    importeDev = bundle.getDouble(“IMPORTE”);

    EntradaLista elegido = mList.get(posicion);
    elegido.setImporte(elegido.getImporte() + importeDev);

    mAdapter.notifyDataSetChanged();
    }
    }

    Como puedes ver, en vez de hacer uso del método onRestoreInstanceState, compruebo el método onCreate para ver si se está recuperando o no, y ahi cojo la lista y monto el adapter en el ListView.

    Cabe destacar que la clase EnntradaLista debe implementar la interface Parcelable para que pueda ser pasado en este tipo de objetos, como son el Bundle o Intent.

    Puede haber algun error, ya que lo he hecho por encima y no he probado nada 😉

    Espero que te sirva de ayuda Javier.

    Saludos!

    • Gracias, la primera parte ya la tengo solventada, lo de actualizar los datos correspondientes.

      ahora me falta lo de guardar los parametros para que no se me pierdan, pero es curioso, no se porque, aunque ago cambio de actividad para pedir datos y retornarlos, no se me pierden al volver, y en el android manifiest puse android:configChanges=”keyboardHidden|orientation|screenSize”, y tampoco se pierden al rotar la pantalla, aun asin voy a intentar de implementar lo que me as explicado para una mayor seguridad y quitare el comando del android manifiest.

      Gracias.
      Javier,,

  9. Hola.

    he intentado implementar la clase EntradaLista con el ejemplo que hay aqui “https://sekthdroid.wordpress.com/2014/01/06/implementar-la-interface-parcelable-en-una-clase-en-android/”, poniendo como variables solo dos Strings Nombre y Importe.
    en la clase EntradaLista no me aparece ningum fallo, pero en las siguientes si.

    en el adaptador meda error al final en el nombre.setText(c.getNombre()); y importe.setText(c.getImporte());:

    public class Adaptador extends ArrayAdapter {

    Activity context;
    ArrayList listaContactos;

    // Le pasamos al constructor el contecto y la lista de contactos
    public Adaptador (Activity context, ArrayList listaContactos) {
    super(context, R.layout.entrada, listaContactos);
    this.context = context;
    this.listaContactos = listaContactos;
    }

    public View getView(int position, View convertView, ViewGroup parent) {

    // Rescatamos cada item del listview y lo inflamos con nuestro layout
    View item = convertView;
    item = context.getLayoutInflater().inflate(R.layout.entrada, null);

    EntradaLista c = listaContactos.get(position);

    // Definimos los elementos que tiene nuestro layout
    TextView nombre = (TextView) item.findViewById(R.id.textoNombre);
    TextView importe = (TextView) item.findViewById(R.id.textoImporte);

    nombre.setText(c.getNombre());
    importe.setText(c.getImporte());

    return (item);
    }

    }

    y en la activity principal es los siguientes comandos:

    if (savedInstanceState==null)
    {
    // esta linea me da error con el siguiente mensaje The method getInstance(MainActivity) is undefined for the type DataSource
    listaContactos = DataSource.getInstance(this).getEntradaLista();

    }
    else
    {
    listaContactos = savedInstanceState.getParcelableArrayList(“LISTA”);
    }

    luego en la linea :
    listaContactos.add(new EntradaLista(InpNombre.getText().toString(),”0.00″));

    y en el onActivityResult en las lineas:
    String Vactual = elegido.getImporte().toString();
    y
    String FmD = df.format(Vtotal);
    elegido.setImporte(FmD); // esta es la que me da error
    adapter.notifyDataSetChanged();

    me puedes echar una manilla.

    Gracias.
    Javier,,

  10. buenas de nuevo, ya solvente el problema.
    tengo una consulta mas ya que no he conseguido salirme por mi mismo, en el codigo que me pusiste para que no se me borraran los datos:

    if (savedInstanceState == null) {
    // Cargamos la lista desde donde sea
    mList = DataSource.getInstance(this).getEntradaLista();
    }else{
    // Recuperamos el estado anterior
    mList = savedInstanceState.getParcelableArrayList(“LISTA”);
    }
    + el de salvar mi listaContacto

    en el primer if quisiera cargar los datos desde un fichero, ya que se ejecuta la primera vez al arrancar, asin podria salir del programa y al entrar continuar con los mismos datos, pero no consigo hacer el grabar y leer de mi arraylist personalizado. en un punto del programa por ejemplo cada vez que inserto un componente, quisiera grabar y recuperar esta informacion al arrancar el programa de nuevo ya que con la implementacion del savedInstanceState ya no pierdo los datos al girar el telefono o si paso de una actividad a otra.

    espero no averme liado con la explicacion.

    Saludos.
    Javier,,

  11. Buenas Javier,

    Pues eso ya es un poco como te lo quieras montar, yo haría un método que leyera todos los datos de un fichero y lo cargara en el ArrayList, el cual usarías para cargar el ListView, y esto dentro del primer if que valida si se ejecuta por primera vez o no. (Hasta aqui es un poco como has dicho tu)

    Para lo siguiente, tal vez te iría mejor guardar todos esos datos una vez finalizas la aplicación completamente, o si bien guardarlos recién crees esa entrada en la propia aplicación. Pero este tema es ya un poco según tengas estructurada la aplicacion, la “capa” de persistencia y el objetivo de la aplicación.

    No he sido mucho de ayuda pero bueno jeje

    Saludos!!

  12. hola buenos dias tengo esto en mi codigo lo que necesito es el llamdo de otras layout pero solo me manda a la mis ma que puedo hacer me podria ayudar

    lista.setOnItemClickListener(new OnItemClickListener() {

    @Override
    public void onItemClick(AdapterView pariente, View view, int posicion, long id) {
    lista_entrada elegido = (lista_entrada) pariente.getItemAtPosition(posicion);

    Intent intent = new Intent(Activitybuscados.this, arellanoActivity.class);
    startActivity(intent);

    • Buenas Alex,

      Perdona que te conteste con demora.

      No entiendo demasiado bien tu problema, pero lo que si veo es que si estás usando un ListView para coger el dato y pasarlo a otra Activity, en esa parte no se vé reflejado, ya que sacas el elegido pero no lo metes en el Intent, por lo que como te decía, si intentas hacer esto, tu item elegido no va a pasar a la siguiente Activity.

      Si me aclaras un poco mas lo que te pasa podría ayudarte mas.

      Saludos

    • Buenas Javi.

      Si lo que quieres es lanzar una Activity cuando se termina algún video, si usas la clase MediaPlayer de Android, tienes a tu disposición unos Callback que te pueden ayudar a la hora de saber cuando un video se ha terminado de reproducir, por lo que cuando esto pasara, simplemente ejecutarías tu método startActivity(intent) para lanzar la activity que desearas.

      Espero haberte sido de ayuda.

      Saludos!

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s