03-Intercambio de Datos Entre Actividades

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 22

INTERCAMBIO DE

DATOS ENTRE
ACTIVIDADES
ANDROID STUDIO
INDICE

ENVIAR DATOS A UNA SEGUNDA ACTIVIDAD .................................................................................... 3


ACTIVIDAD SECUNDARIA DEVUELVE DATOS A LA ACTIVIDAD PRINCIPAL ......................13
EJERCICIOS ........................................................................................................................................................22

2
ENVIAR DATOS A UNA SEGUNDA
ACTIVIDAD

Vamos a hacer un ejemplo para ver mejor los pasos a seguir. Primero crearemos un nuevo
proyecto llamado Enviar y Devolver Información, desde una Empty Activity.

En este ejemplo vamos a hacer una actividad que abra otra, pero pasándole la
información, para que la segunda actividad sea capaz de trabajar con la información
recibida.

La primera actividad tendrá un campo contraseña y un botón de forma que en la primera


actividad rellenarán el password y al pulsar el botón se pasará a otra ventana que
mostrará el contenido del password, como si estuviera desencriptando la contraseña.

En el layout borramos el Texview por defecto y arrastramos un Password del grupo Text
y un Button para desencriptar.

Seleccionamos los dos elementos a la vez y con la tecla cmd hacemos clic en las dos y
ponemos un ancho de 0dp match-constraint en layout_width. El primero lo anclamos a
la parte superior con distancia de 32 y le damos un margen izquierdo y derecho de 16px.
Le ponemos como identificador txtPasswordMain con la propiedad hint el texto
password.

3
Con el botón hacemos lo mismo, lo anclamos a la parte superior (que será el campo de
Password), le damos margen izquierdo y derecho de 16px, el id btnDesencriptarMain y el
texto DESENCRIPTAR.

Vamos a MainActivity.java y empezamos definiendo las variables de la vista:

package com.cieep.a03_enviarydevolverinformacin;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends AppCompatActivity {


private EditText txtPassword;
private Button btnDesencriptar;

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

Después creamos una función para inicializar las variables y la llamamos en el método
onCreate():

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

inicializarVariables();
}

private void inicializarVariables() {


txtPassword = findViewById(R.id.txtPasswordMain);
btnDesencriptar = findViewById(R.id.btnDesencriptarMain);
}

Ahora necesitamos obtener el String de la contraseña y darle la funcionalidad al botón


para enviar el String del password a la segunda actividad para que le muestre con un
Toast.

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

inicializarVariables();

String password = txtPassword.getText().toString();


btnDesencriptar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

}
});
}

Necesitamos crear la segunda actividad. Para ello vamos a la carpeta del proyecto dentro
de java, botón derechoànewàactivityàEmpty Activity

Con la actividad creada vamos al Main y añadimos las siguientes líneas dentro de
setOnClickListener()

5
Intent intent = new Intent(MainActivity.this,
DesencriptarActivity.class);

El hilo conductor de toda transición entre actividades es un Intent en el cual marcamos


cual es la actividad que pide que se abra una nueva ventana (MainActivity.this) y a que
ventana quiere ir (DesencriptarActivity.class).

Podemos hacer la metáfora que el Intent es el vehículo conductor como el Google Maps al
que le especificamos origen y destino. Si queremos llevarnos ropa al viaje necesitamos
una maleta o mochila mágica que no tiene fin y cabe cualquier tipo de cosa.

La mochila es el Bundle, dentro puedo poner lo que quiera, pero con una especificación
le tengo que decir a la mochila que tipo de dato estoy poniendo. Esto lo hago con un put
que tiene dos argumentos, una key y un valor, le paso el nombre de la variable y el valor
de la variable. Esto lo necesitaré para saber qué información vamos a sacar.

Es importante mantener una lógica, porque luego, para sacar la información se tiene que
llamar exactamente igual.

Ahora falta arrancar la actividad, pero antes hay que cargar la maleta en el coche con un
putExtras.

Bundle bundle = new Bundle();


bundle.putString("PASS", password);
intent.putExtras(bundle);
startActivity(intent);

Los Bundles no son obligatorios, aunque si recomendables para reaprovechar ese grupo
de datos en otras actividades.

btnDesencriptar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,
DesencriptarActivity.class);
Bundle bundle = new Bundle();
bundle.putString("PASS", password);
intent.putExtras(bundle);
startActivity(intent);
}
});

Cuando le demos al Play y pulsemos el botón a la segunda ventana le llegará el String.

6
Vamos ahora a hacer el código de la segunda actividad. ¿Que se necesita para abrir una
actividad? Un Intent, toda actividad se crea a partir de un Intent que es el que define toda
la información de esa actividad. El Main es la única actividad que no se crea por un Intent,
aunque esto no es del todo cierto, ya que esta información está en el manifest

<?xml version="1.0" encoding="utf-8"?>


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.03EnviaryDevolverInformación"
tools:targetApi="31">
<activity
android:name=".DesencriptarActivity"
android:exported="false" />
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

Si quisiera cambiar la actividad inicial tendría que cambiar estas líneas a la actividad que
quiero que sea la primera, y cambiar el exported a true en la actividad que ahora
queremos que sea la principal.

¿Porque esta explicación? Para que se entienda que toda actividad ha sido creada por un
Intent y por ese motivo siempre podremos hacer un get al Intent que lo ha creado.

De ese Intent podemos encontrar toda la información de quien la ha creado. Lo primero


que tiene que hacer la actividad para llegar a los datos es obtener el Intent, NO CREAR
UNO NUEVO. Ese Intent tiene dentro un Bundle, que obtendremos de getExtras del Intent

7
que la ha llamado. Para hacerlo bien, sabemos seguro que Intent existe, pero no podemos
estar seguros que el Bundle existe, por eso ponemos el if.

Si es distinto de null recuperamos el String de la key PASS y lo mostramos en un Toast en


la nueva ventana.

package com.cieep.a03_enviarydevolverinformacin;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;

public class DesencriptarActivity extends AppCompatActivity {

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

Intent intent = getIntent();


Bundle bundle = intent.getExtras();

if(bundle != null){
String password = bundle.getString("PASS");
Toast.makeText(this, password,

Toast.LENGTH_SHORT).show();
}

}
}

Hay un error desde el principio, no hay error de compilación, sino de lógica. Tenemos que
ejecutar y ver que está pasando y porque está pasando.

El Toast sale vacío, el error está en el onCreate() de la actividad principal, porque cuando
se crea la actividad aún no se ha escrito nada en el texto.

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

inicializarVariables();

8
String password = txtPassword.getText().toString();
btnDesencriptar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,
DesencriptarActivity.class);
Bundle bundle = new Bundle();
bundle.putString("PASS", password);
intent.putExtras(bundle);
startActivity(intent);
}
});
}

Tendríamos que mover esa línea dentro del onClickListener().

Ahora vamos a montar dentro del paquete principal un nuevo paquete llamado modelos,
para crear nuestras clases de datos, crearemos una java class llamada Usuario.

package com.cieep.a03_enviarydevolverinformacin.modelos;

public class Usuario {


private String email;
private String password;

public Usuario(String email, String password) {


this.email = email;
this.password = password;
}

public String getEmail() {


return email;
}

public void setEmail(String email) {


this.email = email;
}

public String getPassword() {


return password;
}

9
public void setPassword(String password) {
this.password = password;
}

@Override
public String toString() {
return "Usuario{" +
"email='" + email + '\'' +
", password='" + password + '\'' +
'}';
}
}

Vamos a modificar la actividad principal y vamos a añadirle un Email encima. Borramos


la constraint que este hecha e insertamos un texto de tipo Email.

Le cambiamos el id por txtEmailMain, lo hacemos igual de ancho que los otros y en el hint
le ponemos el texto email.

Vamos a la actividad principal e incluimos la variable.

private EditText txtEmail;

y en la función inicializa variables lo inicializamos

private void inicializarVariables() {


txtEmail = findViewById(R.id.txtEmailMain);
txtPassword = findViewById(R.id.txtPasswordMain);
btnDesencriptar = findViewById(R.id.btnDesencriptarMain);
}

Ahora tenemos dos opciones para enviar la información:

LA MALAà igual que hemos definido una variable String para el Password hacemos otra
para el Email. Porque es la mala, porque con un modelo de datos de dos elementos no
cuesta, pero si es un modelo de 20 elementos no es una buena solución.

btnDesencriptar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String email = txtEmail.getText().toString();
String password = txtPassword.getText().toString();
Intent intent = new Intent(MainActivity.this,
DesencriptarActivity.class);

10
Bundle bundle = new Bundle();
bundle.putString("PASS", password);
bundle.putString("EMAIL", email);
intent.putExtras(bundle);
startActivity(intent);
}
});

El email lo pasamos como un campo más y en la secundaria de DesencriptarActivity lo


recuperamos.

protected void onCreate(Bundle savedInstanceState) {


super.onCreate(savedInstanceState);
setContentView(R.layout.activity_desencriptar);

Intent intent = getIntent();


Bundle bundle = intent.getExtras();
if(bundle != null){
String password = bundle.getString("PASS");
String email = bundle.getString("EMAIL");
Usuario user = new Usuario(email, password);
Toast.makeText(this, user.toString(),
Toast.LENGTH_SHORT).show();

}
}

Funciona, pero cuando el objeto tiene más de un par de atributos no es muy práctico.

LA BUENA à Vamos a guardar el objeto en un fichero binario para después ser capaz de
reconstruirlo. A este proceso se le llama serializar un objeto. Si queremos enviar un
objeto la clase se tiene que poder serializar, por este motivo la clase usuario tiene que
implementar la interfaz Serializable.

public class Usuario implements Serializable

Con esto, en lugar de enviar dos Strings como antes el Bundle tiene que enviar un
putSerializable, con una clave y un objeto.

bundle.putSerializable("USER", new Usuario(email, password));

11
En la segunda actividad eliminamos el Email y el Password y modificamos el usuario
pasándole al Bundle con getSerializable y le hacemos un cast a Usuario para que sepa
que el modelo de datos que recibe es de tipo usuario.

Usuario user = (Usuario) bundle.getSerializable("USER")

12
ACTIVIDAD SECUNDARIA
DEVUELVE DATOS A LA ACTIVIDAD
PRINCIPAL

Vamos a crear una clase Direccion dentro del paquete modelos.

package com.cieep.a03_enviaryrecibirinformacin.modelos;

public class Direccion {


private String calle;
private int numero;
private String ciudad;

public Direccion(String calle, int numero, String ciudad) {


this.calle = calle;
this.numero = numero;
this.ciudad = ciudad;
}

public String getCalle() {


return calle;
}

public void setCalle(String calle) {


this.calle = calle;
}

public int getNumero() {


return numero;
}

public void setNumero(int numero) {


this.numero = numero;
}

public String getCiudad() {


return ciudad;
}

public void setCiudad(String ciudad) {


this.ciudad = ciudad;
}

@Override
public String toString() {
return "Direccion{" +
"calle='" + calle + '\'' +
", numero=" + numero +
", ciudad='" + ciudad + '\'' +
'}';
}
}

13
Creamos una actividad de tipo Empty que sea capaz de crear objetos de tipo Direccion

Modificamos la vista le añadimos un TextView, un PlainText, un Number, un PlainText y


un Button y lo dejamos de forma similar a la siguiente imagen:

14
Añadimos el identificador txtCalleCreateDir, le borramos el texto y le ponemos como hint
el texto Calle.

Le añadimos el identificador txtNumeroCreateDir con el hint Numero.

Al último texto le añadimos el identificador txtCiudadCreateDir, le borramos el texto y le


ponemos como hint Ciudad.

Por último, modificamos el botón con el id btnCrearCreateDir, modificamos el texto a


Crear Direccion.

Vamos a la clase CreateDirActivity y creamos los atributos

package com.cieep.a03_enviaryrecibirinformacin;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;

public class CreateDirActivity extends AppCompatActivity {


private EditText txtCalle;
private EditText txtNumero;
private EditText txtCiudad;
private Button btnCrear;

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

inicializaVistas();

btnCrear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Direccion direccion = new
Direccion(txtCalle.getText().toString(),
Integer.parseInt(txtNumero.getText().toString()),
txtCiudad.getText().toString());
}
});

private void inicializaVistas() {


txtCalle = findViewById(R.id.txtCalleCreateDir);
txtNumero = findViewById(R.id.txtNumeroCreateDir);
txtCiudad = findViewById(R.id.txtCiudadCreateDir);
btnCrear = findViewById(R.id.btnCrearCreateDir);
}
}

15
Para poder devolver el objeto dirección hace falta un Bundle. Para poder serializarlo la
clase Direccion debe implementar la interfaz Serializable.

Podemos hacerlo directamente desde el error eligiendo la opción correcta:

Toda información que viaje va dentro de un Bundle(maleta) y todo Bundle ira dentro de
un Intent(coche).

Como es un “viaje de ida y vuelta” y cuando salgo le digo de donde salgo y a donde voy,
cuando vuelva no será necesario que le diga nada, por lo que creamos un Intent vacío, al
que le pondremos la “maleta”.

Para volver al destino la actividad actual tiene que destruirse, como va a terminar
tenemos que decirle el motivo de la terminación. Si el usuario le da al botón de atrás
automáticamente hace lo mismo que Cancelar. Si el usuario le dio al botón de Guardar
tenemos que hacer un setResult para especificar que todo ha ido bien y le enviamos los
datos.

Por ultimo invoca la función finish().

btnCrear.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Direccion direccion = new
Direccion(txtCalle.getText().toString(),
Integer.parseInt(txtNumero.getText().toString()),
txtCiudad.getText().toString());

Bundle bundle = new Bundle();


bundle.putSerializable("DIR", direccion);
Intent intent = new Intent();
intent.putExtras(bundle);
setResult(RESULT_OK, intent);
finish();
}
});

16
Vamos a poner un botón de CrearDireccion en la vista del MainActivity con id
btnCrearDirMain y texto Crear Direccion

public class MainActivity extends AppCompatActivity {


private EditText txtEmail;
private EditText txtPassword;
private Button btnDesencriptar;
private Button btnCrearDir;

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

inicializarVariables();

btnDesencriptar.setOnClickListener(new
View.OnClickListener() {
@Override
public void onClick(View view) {
String email = txtEmail.getText().toString();
String password = txtPassword.getText().toString();
Intent intent = new Intent(MainActivity.this,
DesencriptarActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable("USER", new Usuario(email,
password));
intent.putExtras(bundle);
startActivity(intent);
}
});

btnCrearDir.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

}
});
}

private void inicializarVariables() {


txtEmail = findViewById(R.id.txtEmailñMain);
txtPassword = findViewById(R.id.txtPasswordMain);
btnDesencriptar = findViewById(R.id.btnDesencriptarMain);
btnCrearDir = findViewById(R.id.btnCrearDirMain);
}
}

Para abrir actividades hemos utilizado el startActivity(), pero tiene un “hermano mayor”
capaz de hacer más cosas que esta deprecated, que es el startActivityForResult() lo que
hace es decir a Android que abra una actividad, pero cuando esa actividad se termine se
ejecutará una función para recuperar los datos que me devuelva.

17
Vamos a hacer una metáfora con el envío de una carta. Podemos hacer una carta y hacer
un envío normal y luego despreocuparnos. Pero también podemos hacer una carta con
acuse de recibo y dependiendo si llega o no actuar en consecuencia.

El startActivity() arranca la actividad y se despreocupa, pero el starActivityForResult() lo


que hace es arrancar la actividad, pero cuando esa actividad termine tenemos que hacer
algo. ¿Cuántas cartas se pueden enviar con acuse de recibo? Todas las que queremos, por
este motivo tenemos que marcar que carta es la que ha llegado para actuar en
consecuencia según la que ha llegado.

Tenemos que generar algún tipo de tag o índice para poder identificar qué actividad ha
terminado y con eso actuar en consecuencia.

La forma más simple de hacerlo es usando constantes, de forma que el número de las
constantes sea diferente.

private final int DIRECCIONES = 123;

Para lanzar la actividad necesitamos un Intent y lanzar la actividad con


starActivityForResult().

btnCrearDir.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,
CreateDirActivity.class);
startActivityForResult(intent, DIRECCIONES);
}
});

Este startActivityForResult() hará que se ejecute un método que tienen todas las
actividades que será onActivityResult(). Aunque lo marca como deprecated hace poco
que lo está, y habrá muchas aplicaciones que aún lo utilicen. Por este motivo vamos a
verlo de esta forma y luego veremos la nueva forma que lo sustituye.

@Override
protected void onActivityResult(int requestCode, int resultCode,
@Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);

Este método recibe un requestCode para que sepamos que ventana se ha cerrado, un
resultCode para que sepamos en qué estado se ha cerrado y un Intent que puede ser
Nullable porque puede que vuelva vacío.

18
Para poner comentarios de función /** sobre la función + INTRO

/**
* Se activa al retornar de un starActivityForResult y dispara las
acciones necesarias
* @param requestCode -> identificador de la ventana que se ha
cerrado "el tipo de dato que retorna"
* @param resultCode -> el modo en que se ha cerrado la ventana
* @param data -> Datos retornados (Intent con un Bundle dentro)
*/
@Override
protected void onActivityResult(int requestCode, int resultCode,
@Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);

Lo primero que debería hacer esta función es averiguar que ventana se ha cerrado, y
luego averiguar si se cerró por Guardar, por último comprobar si hay un Intent.

/**
* Se activa al retornar de un starActivityForResult y dispara las
acciones necesarias
* @param requestCode -> identificador de la ventana que se ha
cerrado "el tipo de dato que retorna"
* @param resultCode -> el modo en que se ha cerrado la ventana
* @param data -> Datos retornados (Intent con un Bundle dentro)
*/
@Override
protected void onActivityResult(int requestCode, int resultCode,
@Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);

if(requestCode == DIRECCIONES){
if(resultCode == RESULT_OK){
if(data != null){
Bundle bundle = data.getExtras();
Direccion dir = (Direccion)
bundle.getSerializable("DIR");
Toast.makeText(this, dir.toString(),
Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this, "No hay datos",
Toast.LENGTH_SHORT).show();
}
}else{
Toast.makeText(this, "Ventana Cancelada",
Toast.LENGTH_SHORT).show();
}
}

Con esto debería funcionar.

19
Este método está obsoleto porque las buenas prácticas de utilizar constantes no son
usadas por los programadores todo lo que se debería y porque si pueden volver muchas
actividades podemos hacer un método de 1000 o 2000 líneas para dar respuesta a cada
una de ellas de forma independiente.

Aunque se ha cambiado la forma de trabajar, la lógica es la misma. Lo que se ha hecho es


independizar los eventos de onActivityResult() por cada uno de los elementos que me van
a poder lanzar una devolución de datos.

Creamos tareas en segundo plano, para poder hacer eso se ha creado un nuevo tipo de
datos, un objeto que es el ActivityResultLauncher. Definimos como quiero que se lance la
actividad y que quiero que haga en al caso hipotético que requiera un resultado.

Hacemos lo mismo que antes, pero en sitios diferentes.

Primero definimos los Launches:

private ActivityResultLauncher<Intent> launcherDirecciones;

Lo siguiente que necesitamos es especificar que va a hacer ese Launcher

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

inicializarVariables();
inicializarLaunches();

btnDesencriptar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String email = txtEmail.getText().toString();
String password = txtPassword.getText().toString();
Intent intent = new Intent(MainActivity.this,
DesencriptarActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable("USER", new Usuario(email,
password));
intent.putExtras(bundle);
startActivity(intent);
}
});

btnCrearDir.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,
CreateDirActivity.class);

20
startActivityForResult(intent, DIRECCIONES);
}
});
}

private void inicializarLaunches() {


//registrar una actividad de retorno con dos partes
// 1. Como lanzo la actividad hija (equivalente a
startActivityForResult)
// 2. Que hago cuando mi hija termine (equivalente al metodo
onActivityResult)
launcherDirecciones = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result)
{
if(result.getResultCode() == RESULT_OK){
if(result.getData() != null){

Bundle bundle =
result.getData().getExtras();
Direccion dir = (Direccion)
bundle.getSerializable("DIR");
Toast.makeText(MainActivity.this,
dir.toString(), Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(MainActivity.this, "No
hay datos", Toast.LENGTH_SHORT).show();
}
}else{
Toast.makeText(MainActivity.this, "Ventana
Cancelada", Toast.LENGTH_SHORT).show();
}
}
}
);
}

Falta el último paso que es sustituir la llamada a startActivityForResult() por lanzar el


Launcher:

btnCrearDir.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this,
CreateDirActivity.class);
// startActivityForResult(intent, DIRECCIONES);
launcherDirecciones.launch(intent);
}
});

21
EJERCICIOS

1. Hacer una actividad que permita escribir una frase y que tenga dos botones que
vayan a la misma actividad, pero que uno resuelva cuantos caracteres tiene la
frase y otro que diga cuantas palabras tiene esa misma frase.

2. Hacer una actividad que tenga

a. 3 campos de texto, uno para mostrar la cantidad de coches que hay


almacenados, otro para mostrar la cantidad de motos que hay
almacenadas y otro para indicar la cantidad de bicis que hay almacenadas

b. 3 botones, uno para pasar a una actividad nueva que permite crear coches
(marca, modelo y color) , otro que permite crear motos (marca, modelo y
cilindrada) y otro que permite guardar bicis (marca y pulgadas). Cuando
se cree el objeto seleccionado se cerrará la actividad volviendo a la
principal y actualizando el número de objetos totales de esa lista.

22

También podría gustarte