40 comentarios el “Crear ListView Básico en Android

  1. Pingback: Cargar ListView con AsyncTask en Android « SekthDroid

  2. saludos, hay una manera de cargar nuevamente el adapter con nuevos datos sin que se borren los anteriores,
    si ya cargue 20 elemntos y los estoy mostrando , quiero que se carguen otros 20 pero sin borrar los primeros 20 e intentado de las siguientes formas pero no me deja y marca error
    for (int i=0;i<lstProductos.length;i++){
    adaptador.add(lstProductos[i]);
    }

    adaptador.addAll(lstProductos);

    las 2 formas me dan error
    }

    • Buenas tardes Beto, lo que debes hacer es añadir los 20 elementos al List, y una vez lo tengas, usar el método adaptador.notifyDataSetChanged(). Este método notifica que el contenido ha cambiado, y por tanto se refresca. Te pongo un ejemplo que acabo de hacer:

      public class MainActivity extends Activity {
      	private EditText txtTexto;
      	private Button btnAgregar;
      	private ListView listaItems;
      	private List<String> sistemas = new ArrayList<String>();
      
      	@Override
      	protected void onCreate(Bundle savedInstanceState) {
      		super.onCreate(savedInstanceState);
      		setContentView(R.layout.activity_main);
      
      		// Cargamos la List
      		sistemas.add("Windows");
      		sistemas.add("Ubuntu");
      		sistemas.add("Mac OSX");
      		sistemas.add("Solaris");
      
      		// Instanciamos las View
      		txtTexto = (EditText) findViewById(R.id.txtTexto);
      		btnAgregar = (Button) findViewById(R.id.btbAgregar);
      		listaItems = (ListView) findViewById(R.id.lista);
      
      		// Creamos el ArrayAdapter<String>
      		final ArrayAdapter<String> adapter = new ArrayAdapter<String>(
      				MainActivity.this, android.R.layout.simple_list_item_1,
      				sistemas);
      
      		// Establecemos el Adapter
      		listaItems.setAdapter(adapter);
      
      		// Establecemos la funcionalidad del botón
      		btnAgregar.setOnClickListener(new OnClickListener() {
      
      			@Override
      			public void onClick(View v) {
      				// TODO Auto-generated method stub
      				if (txtTexto.getText().toString().length() == 0) {
      					// Si el EditText no contiene nada, mostramos un mensaje
      					Toast.makeText(getApplicationContext(),
      							"No ha introducido nada", Toast.LENGTH_SHORT)
      							.show();
      				} else {
      					// Cargamos mas elementos en la Lista
      					sistemas.add(txtTexto.getText().toString());
      					
      					// Notificamos que hay cambios
      					adapter.notifyDataSetChanged();
      				}
      			}
      
      		});
      
      	}
      
      }
      
      

      Como ves, he agregado elementos en el objeto de la clase List, no en el adapter (que tambien se podría). Y mediante el método, se agregan los nuevos elementos. Esto pasa porque el objeto de la clase ArrayAdapter sigue manteniendo una referencia al objeto de List que has usado para cargarlo previamente.

      Saludos!, espero que te sea de ayuda!!!

      PD: Puedes descargar el ejemplo aquí.

  3. Saludos hay una forma de agregar 2 valores a la lista pero solo mostar uno por ejemplo cargar la lista con 2 campos (id_cte, nombre_cte), pero que en la lista solo se muestre el nombre y cuando yo seleccione un nombre leer el id_cte y ponerlo en unEdittext??
    es que lo hice pero utilizando 2 listas (una lista para cada uno de los campos) y cuando selecciono un nombre obtengo su posicion y la busco en la otra lista para poder obtenerlo

    es similar al valuemember y displaymember que utiliza VB.net

    • Una opción que podría serte válida es la de crear un “ListView” personalizado, el cual va a contener su propio BaseAdapter, el cual debes crear a mano, y también debes implementar sus métodos, uno de ellos te puede servir, ya que se llama getItemId, en el cual puedes implementarlo como quieras si no me equivoco.

      La idea sería crear algo como lo siguiente:

      package sekth.droid.lvPersonalizado;
      
      import java.util.List;
      
      import android.app.Activity;
      import android.content.Context;
      import android.view.LayoutInflater;
      import android.view.View;
      import android.view.ViewGroup;
      import android.widget.BaseAdapter;
      import android.widget.TextView;
      
      public class MyAdapter extends BaseAdapter {
      	private List<Item> items;
      	private Activity activity;
      	
      	public MyAdapter(Activity activity, List<Item> items){
      		this.items = items;
      		this.activity = activity;
      	}
      
      	public static class ViewHolder {
      		public TextView id_cte;
      		public TextView nombre_cte;
      	}
      
      	@Override
      	public View getView(int position, View convertView, ViewGroup parent) {
      		// TODO Auto-generated method stub
      		View v = convertView;
      		ViewHolder holder;
      		if (v == null) {
      			LayoutInflater inflater = (LayoutInflater) activity
      					.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
      			v = inflater.inflate(R.layout.fila_cte, null);
      			holder = new ViewHolder();
      			holder.id_cte = (TextView) v.findViewById(R.id.tvIdCte);
      			holder.nombre_cte = (TextView) v.findViewById(R.id.tvNombreCte);
      			v.setTag(holder);
      		} else {
      			holder = (ViewHolder) v.getTag();
      		}
      
      		final Item item = items.get(position);
      		if (item != null) {
      			holder.id_cte.setText(String.valueOf(item.getId_cte()));
      			holder.nombre_cte.setText(item.getNombre_cte());
      		}
      
      		return v;
      	}
      
      	@Override
      	public int getCount() {
      		// TODO Auto-generated method stub
      		return items.size();
      	}
      
      	@Override
      	public Object getItem(int position) {
      		// TODO Auto-generated method stub
      		return items.get(position);
      	}
      
      	@Override
      	public long getItemId(int position) {
      		// TODO Auto-generated method stub
      		return items.get(position).getId_cte();
      	}
      
      }
      
      

      Si quieres ahora lo comento bien y te lo subo para que lo tengas 🙂

      Saludos!!!

    • una duda como puedo hacer para qe el getitemid sea String?
      ya lo cambie y me da error??? y el cod_cte es string

      o solamente creo otro metodo qe me retorne un string??

      • Puedes crear un método en la clase MyAdapter que sea del tipo:

        public String getItemCod(int position){
        		return items.get(position).getCod_cte();
        	}
        

        Y con esto, en el onItemClickListener cambiar un poco:

        Toast.makeText(getBaseContext(), "Cod: " + adapter.getItemCod(position), Toast.LENGTH_SHORT).show();
        

        Otra cosa es que para hacerlo de esta manera, tienes que hacer que el objeto adapter sea final para poder ser accedido desde dentro.

        Saludos!!!

  4. ya cargo la lista y el adapter pero cuando muestro la lista siempre si tengo 10 coincidencias con el texto me aparece 10 veces el ultimo cliente qe guarde en la lista asi:

    cliente 1 – 1
    cliente 1 – 1
    cliente 1 – 1
    cliente 1 – 1

    a qu se puede deber esto no se si en MyAdapter tenga qe hacer un ciclo for para guardar cada uno de los items de la lista, ya qe en el ejemplo que me diste colocaste un if
    saludos

    • A ver si entiendo exactamente lo que pasa:

      Introduces texto, y vas recibiendo coincidencias, esas coincidencias se van añadiendo al ListView, pero la última se agrega 10 veces seguidas,

      Por otro lado, la clase MyAdapter se ocupa de adaptar el contenido de un objeto de la clase List a un ListView, por tanto si lo que queremos es que las cosas salgan rápido, deberíamos quitarle trabajo al MyAdapter

      Lo mejor será meter un Log. para comprobar por donde puede estar dandose un problema, y vemos por donde falla.

      Saludos!!

      • perdon es que este comentario nolo avia visto!!!

        pero no sucede asi como lo explicas
        lo qe pasa es esto yo tengo todo guardado en la base de datos SQlite
        por ejemplo cuando escribo algo en el edittext se ejecuta mediante asynctask una consulta a la base de datos qe me trae todos los registros qe tengan coincidencia con el filtro qe mando (edittext), por decir qe encontro 10 coincidencias en total la consulta.
        entonces en el listview se muestra 10 veces el ultimo registro (solo me muestra este 10 veces), nada mas

        por lo qe los 10 registros qe muestro en el listview son el mismo

  5. en esta parte del codigo:
    public View getView(….){
    ………..
    final Productos item = items.get(position);
    if (item != null) { <— Aqui no deberia ir un for qe recorra la lista items?????
    holder.codprod.setText(String.valueOf(item.getCodprod()));
    holder.descripcion.setText(item.getDescripcion());
    }
    return v;
    }

    aqui una imagen de com aparece

    • Jejeje no, el funcionamiento interno del Adapter es diferente:

      Pongamos que le pasas al adapter una lista de 20 objetos de la clase Producto por ejemplo.

      Lo que el adapter hace es llamar al método getView por cada objeto que exista en la lista, y devuelve la View que será una fila por cada elemento de la lista.

      -Tu has pasado una lista de 20 objetos.
      -El método getView se ejecuta tantas veces como objetos existan en la lista

      Ese bloque if lo que hace es comprobar que un objeto de la clase Producto que no haya sido instanciado se cuele y haga crash. Es decir evita que acciones como:

      Producto item = null;
      listaItems.add(item);
      
      • entonces a qe se puede deber qe me muestre el mismo producto varias veces????
        por medio del log revice la lista y si se envia con todos los valores

      • Para que me sea mas fácil consultarlo, haz lo siguiente:

        Bucle for que imprima en el log el producto cuando la lista se haya cargado (antes de establecer el adapter)

        Log antes del return en el getView con el producto que se está obteniendo

        Bucle for una vez que el adapter haya sido establecido de la lista que muestre el producto.

        A ver si así lo veo mejor 🙂

        Saludos!!!

        PD: Si quieres sube el log en archivo de texto al dropbox y ponme el link 🙂

      • el set adapter lo realizo al inicio del programa en el onCreate
        y cada qe modifico la lista uso: adaptador.notifyDataSetChanged();
        para qe acepte los cambios (esto en esynctask)

      • Mas o menos x’D.

        Lo que intento hacer es reducir lo máximo el bloque de código para ver donde se añaden los elementos repetidos, ya que no es normal.

        Lo mejor será comprobar que datos hay en el List antes del adapter (que eso sale en el log), y los datos que hay en el List después de establecer el adapter, para ver si se han producido cambios dentro de el, y así centrar toda la atención en lo que esté pasando dentro de MyAdapter.

        Si los datos de la List antes de crear el MyAdapter son los mismos que después de crear el MyAdapter y establecerlo, quiere decir que se están añadiendo cosas que no deberían añadirse ahí dentro.

        Saludos!!

      • la variable de producto no se inicializaba en cada vuelta del ciclo por eso se repetia solo el ultimo dato qe almacenaba, pero con lo anterior me sirvio para reducir el codigo
        saludos

  6. hola tengo un adapter personalizado en el qe muestro diferentes detalles de un producto nombre, desc etc, ademas tengo un checkbox,
    con el check box lo que quiero es marcar los elemento qe deseo eliminar de la lista
    cuando presion el boton eliminar recorro la lista
    aqui esta lo que quiero saber
    como puedo obtener el valor del checkbox (checked =true/false) para eliminarlo de la base de datos

    este codigo es el qe tengo en el boton eliminar
    for(int i=0;i<lstDet.size();i++){
    if(lstDet.get(i).getEliminar() ){
    String cod_prod=lstDet.get(i).getCod_prod();
    db.delete("delete from mpedcte", "cod_prod="+cod_prod, null);
    }

    o como puedo hacerlo??
    saludo sy gracias

  7. Buenas Beto,

    Una manera posible de hacerlo es tener una variable de instancia en la Clase del producto, que sea del tipo de dato boolean, y al cual le vayas aplicando true o false según vayas clickeando (y cambiando el valor del CheckBox).

    Con esto, podrías hacer una comprobación con un bucle for como bien haces.

    De otro modo, si tu aplicación está enfocada para un dispositivo con una API 11 o mayor, tienes la oportunidad de hacer que la ListView tenga múltiple elección:

    getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    

    Una vez esto, puedes llamar a un método de la siguiente manera:

    // Obtiene la cantidad de elementos que están seleccionados
    int count = getListView().getCheckedItemCount();
    				
    // Obtiene un array con los ID de los item seleccionados
    long[] checkedId = getListView().getCheckedItemIds();
    

    Como vés, este segundo método es bastante útil y fácil de implementar, así que sería cuestión de tu necesidad respecto al rango de dispositivos que quieras abarcar.

    Espero que te sea de ayuda.

    Saludos!

  8. en la clase producto ya tengo declarada la propiedad de tipo boolean pero cuando pongo el checkbox como checked=true este no se actualiza en la clase por lo que siempre que entra en el ciclo me aparece como false por lo que nunca elimina nada

    • y como puedo agregar el evento onclick para cambiar el valor de la propiedad checked true/false
      esto seria en el adapter que cree para guardar las vistas

      • Según he estado leyendo sobre los CheckBox en distintos foros y páginas, hay un problema con los CheckBox, ya que no se guardan sus valores, y como en la ListView se van reciclando las listas, estos valores se ván perdiendo y me parece que salían casi todos true.

        Si puedes enseñarme la clase de tu Adapter, para ver como lo haces quizás te pueda ayudar mejor y así veo mejor el problema, o mediante algún link a DropBox.

        Saludos!!

  9. Buenas Beto,

    He estado haciendo mis pruebas, y he logrado que funcione, no sé si es el mejor método para hacerlo, por lo que ya depende de tí ver si está bien o no 🙂

    Aquí tienes el link: https://dl.dropbox.com/u/64059675/ExampleCodes/MultipleCheckBoxExample.zip

    Notarás que en vez de usar BaseAdapter he usado ArrayAdapter para hacer el Adapter del ListView, pero es lo de menos.

    He declarado 2 métodos, uno que hace que se establezca el boolean del item, y a continuación se establezca el CheckBox y otro método que retorna una Lista con los ID de los elementos que han sido marcados.

    En el XML he quitado que el chekbox sea clickable y focusable, por tanto se activará o desactivará cuando se pulse cada fila del ListVIew.

    Espero que te sirva de ayuda, y vuelvo a decir que no sé si es el método mas eficaz de manejar este caso, y si tu app es para APIs superiores a la 11, puedes usar lo que te puse en un anterior comentario, que es bastante eficaz.

    Saludos!!

  10. Hola mira quierollenar un ListView con los datos que llegan desde una base de datos (Sqlite) Me podrias colaborar como lo haria? Muchas Gracias

    • Buenas Brandon,

      Justo tengo una entrada que habla sobre esto.

      Consiste en tener una base de datos SQLite y extraer sus datos para mostrar en un ListView, además de poder agregar nuevos elementos en la base de datos.

      Puedes consultarlo aquí.

      Espero que te sea de ayuda Cesar.

      Saludos!!

  11. Hola, tengo una duda, mira yo recibo datos de un WebService pero de dos metodos diferentes los 2 me regresan una lista en formato Json, lo que tengo que hacer es llenar una lista donde al principio me aparezcan los datos de un metodo y despues los datos de otro metodo en la misma lista

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