0 votos

Buenas tardes… por aquí estoy otra vez. Os pego el código del Adapter para llenar un listview y luego os comento:

public class Adaptador extends BaseAdapter { // implements OnClickListener {

static class ViewHolder {
ImageView imagenview;
TextView text_nombre;
TextView text_descripcion;
TextView text_indice;
TextView text_fecha;
ProgressBar progreso;
}

private Cursor datos;
private LayoutInflater inflater = null;

public Adaptador(Context contexto, Cursor valores) {
super();
this.datos = valores;
inflater = LayoutInflater.from(contexto);
datos.moveToLast();
datos.moveToFirst();
}

@Override
public int getCount() {
return datos.getCount();
}

@Override
public Object getItem(int posicion) {
return datos.moveToPosition(posicion);
}

@Override
public long getItemId(int posicion) {
return posicion;
}

@Override
public View getView(int posicion, View convertView, ViewGroup parent) {

final ViewHolder holder;

if (convertView == null) {

convertView = inflater.inflate(R.layout.itemlistalugares, parent,
false);

holder = new ViewHolder();

holder.imagenview = (ImageView) convertView
.findViewById(R.id.lst_foto);
holder.text_nombre = (TextView) convertView
.findViewById(R.id.lst_nombre);
holder.text_descripcion = (TextView) convertView
.findViewById(R.id.lst_descripcion);
holder.text_indice = (TextView) convertView
.findViewById(R.id.lst_indice);
holder.text_fecha = (TextView) convertView
.findViewById(R.id.lst_fecha);
holder.progreso = (ProgressBar) convertView
.findViewById(R.id.muestroProgreso);

convertView.setTag(holder);

} else {

holder = (ViewHolder) convertView.getTag();

}

getItem(posicion);

if (datos.getString(datos.getColumnIndex(“foto”)) != null) {
holder.progreso.setVisibility(View.VISIBLE);
transformoImagen(holder.imagenview, holder.progreso,
Uri.parse(datos.getString(datos.getColumnIndex(“foto”))));

}

holder.text_nombre.setText(datos.getString(datos
.getColumnIndex(“nombre”)));
holder.text_descripcion.setText(datos.getString(datos
.getColumnIndex(“descripcion”)));
holder.text_indice.setText(datos.getString(datos.getColumnIndex(“id”)));

holder.text_fecha
.setText(datos.getString(datos.getColumnIndex(“fecha”)));

// holder.text_nombre.setOnClickListener(this);
// holder.text_descripcion.setOnClickListener(this);
// holder.imagenview.setOnClickListener(this);

// convertView.setLongClickable(true);

return convertView;
}

private void transformoImagen(final ImageView laImagen,
final ProgressBar progreso, final Uri uri) {

//si no hago esto no consigo saber el tamaño del imageview para escalar la foto
//y no entiendo por qué, en otros sitios leo perfectametne el height y width sin problema en el onCreateView
ViewTreeObserver viewTreeObserver = laImagen.getViewTreeObserver();
viewTreeObserver.addOnPreDrawListener(new OnPreDrawListener() {

@Override
public boolean onPreDraw() {

laImagen.getViewTreeObserver().removeOnPreDrawListener(this);

int ancho = laImagen.getWidth();

//AsyncTask para convertir la foto en otro hilo y no parar el resto de la aplicación
//le paso el imageview, el progressbar y el ancho que quiero para la nueva foto, así como la uri de la foto a convertir
//como dato de entrada, lo otro va al constructor.
//al final devuelve un BitMap que cargo en el imageview que le paso
new Convierto(laImagen, progreso, ancho).execute(uri);
return true;
}
});

}
}

A ver… básicamente lo que hace es llenar un listview personalizado con una imagen, dos textview con info, otro textview oculto con un ínidce para enlazarlos con una base de datos, un progressbar para indicar que se está trabajando escalando la foto en otro hilo y otro textview con la fecha de asiento del registro mostrado.
 

La lista se carga bien, y funciona la relación con la base de datos, al clickar sobre cada item puedo identificar correctamente su info en la base de datos.

El problema que tiene, es que en el primer elemento de la lista que se visualiza en pantalla, mientras se carga la misma, veo como todas las fotos de los demás elementos de la lista se visualizan una detrás de otra en el imageview del primer item, y al final no necesariamente queda la foto que corresponde a ese elemento. Si clicko en él la info es correcta, incluso la de la foto aunque la que veo no es la que le corresponde. Cada vez que refresco la lsita, sucede lo mismo pero puede variar la foto que veo, no siempre es la misma.

He repasado el adapter una y otra vez y no acierto a descifrar qué está pasando.

A ver si me podéis echar un cable.

Muchas gracias por anticipado.

Un saludo

preguntado por Nitram Dic 22, 2014 en Android

1 Respuesta

0 votos
Mejor respuesta

Es un problema de sobrescritura del mismo id de la la misma ImageView del mismo holder, ya que está apuntando siempre al mismo elemento cuando se realiza la carga en segundo plano. Hay que tener un poco de cuidado con esto, pero lo más aconsejable es que cuando se descargue la imagen se redibuje la fila del listado (he incluso mantenerlas en un HashMap con SoftReference para que no nos tire la memoria, y realizar un cacheado de imágenes, aunque esto complica. Puedes mirar esto en http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html)

respondido por Jarroba [Admin] Dic 22, 2014
Está puesto. Hay que tener una buena gestión de Views en Listados: Viewholder, cacheado, carga dinámica, etc
Gracias por responder, pero soy nuevo en el ambiente de programación, creo que sería mejor que me lo expliquen con peras y manzanas, jajaja

Ok, tengo entendido que carga las imagenes en el mismo imageview, y que alli radica el problema, o seaique tengo que utilizar viewholder, cacheado, carga dinamica?

Disculpa mi ignorancia

Gracias por contestar
Muchas gracias, probaré a ver que tal me va, luego aviso si me funciono
Mi aplicación ya implementaba estas soluciones que me mencionaste, solo note que en vez de Viewholder tengo un Placeholder, crees que eso afecta?