ListView en ArrayAdapter orden se mezcla cuando se desplaza

Tengo un ListView en un ArrayAdapter personalizado que exhibe un icono ImageView y un TextView en cada fila. Cuando hago la lista lo suficiente para que pueda desplazarse por ella, el orden comienza a la derecha, pero cuando empiezo a desplazarse hacia abajo, algunas de las entradas anteriores comienzan a volver a aparecer. Si vuelvo a desplazarme hacia arriba, el orden antiguo cambia. Hacer esto repetidamente con el tiempo hace que todo el orden de la lista sea aparentemente aleatorio. Por lo tanto, desplazar la lista está haciendo que el orden hijo cambie, o el dibujo no se está actualizando correctamente.

¿Qué podría hacer que algo así sucediera? Necesito el orden en que los elementos se muestran al usuario para que sean del mismo orden en que se agreguen a ArrayList, o por lo menos para permanecer en un orden estático. Si necesito proporcionar información más detallada, por favor hágamelo saber. Cualquier ayuda es apreciada. Gracias.

Tenía problemas similares, pero al hacer clic en un elemento de la lista personalizada, los elementos de la pantalla se invertirían en secuencia. Si volvía a hacer clic, volverían a donde estaban originalmente.

Después de leer esto, he comprobado mi código donde sobrecarga el método getView. Estaba obteniendo la vista desde el convertido, y si era nulo, ahí es cuando construiría mis cosas. Sin embargo, después de colocar un punto de interrupción, encontré que estaba llamando a este método en cada clic y en clics subsiguientes, el convertido no era nulo por lo tanto los elementos no estaban siendo establecidos.

He aquí un ejemplo de lo que era:

public View getView(int position, View convertView, ViewGroup parent) { View view = convertView; if (view == null) { LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = vi.inflate(R.layout.listitemrow, null); RssItem rssItem = (RssItem) super.getItem(position); if (rssItem != null) { TextView title = (TextView) view.findViewById(R.id.rowtitle); if (title != null) { title.setText(rssItem.getTitle()); } } } return view; } 

El cambio sutil está moviendo la abrazadera cercana para el cheque nulo en la vista justo después de inflar:

 public View getView(int position, View convertView, ViewGroup parent) { View view = convertView; if (view == null) { LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = vi.inflate(R.layout.listitemrow, null); } RssItem rssItem = (RssItem) super.getItem(position); if (rssItem != null) { TextView title = (TextView) view.findViewById(R.id.rowtitle); if (title != null) { title.setText(rssItem.getTitle()); } } return view; } 

Espero que esto ayude a otros que experimentan este mismo problema.

Para aclarar más la respuesta de los farcats abajo en una manera más general, aquí está mi explicación:

La operación vi.inflate (necesaria aquí para analizar el diseño de una fila de XML y crear el objeto de vista adecuado) está envuelta por una sentencia if (view == null) para la eficiencia, por lo que no sucederá la inflación del mismo objeto Una y otra vez cada vez que aparece a la vista.

SIN EMBARGO, las otras partes del método getView se usan para establecer otros parámetros y por lo tanto NO se deben incluir en la sentencia if (view == null) .

Similarmente, en otra implementación común de este método, algunos elementos textView, ImageView o ImageButton necesitan ser poblados por valores de la lista [position], usando findViewById y después de las operaciones .setText o .setImageBitmap . Estas operaciones deben venir después de crear una vista desde cero por inflación y obtener una vista existente si no es nula.

Otro buen ejemplo donde se aplica esta solución para BaseAdapter aparece en BaseAdapter haciendo que ListView salga de orden cuando se desplaza

El ListView reutiliza los objetos de vista cuando se desplaza. ¿Está anulando el método getView? Usted necesita cerciorarse de fijar cada característica para cada visión, no asuma que recordará lo que usted tenía antes. Si publica ese método, es probable que alguien le señale en la parte que es incorrecta.

Tengo un ListView, un AdapterView y un View (search_options) que contiene EditText y 3 Spinners. Los elementos ListView son copias múltiples del diseño (search_options), donde el usuario puede agregar más opciones en ListView y luego hacer clic en buscar para enviar una consulta SQL construida de acuerdo con las opciones de los usuarios.

Encontré que la mezcla de conversión indecies así que agregé una lista global (myViews) en actividad y lo pasé a ArrayAdapter. Luego en ArrayAdapter (getView) agrego cada vista recién agregada a ella (myViews).

También en getView en lugar de comprobar si convertView es nulo, compruebo si la lista global (myViews) tiene una vista en el seleccionado (posición) .. Solucionado totalmente los problemas después de perder 3 días leyendo el Internet !!

1- en Actividad añada esto:

 Map<Integer, View> myViews = new HashMap<>(); 

Y luego pasarlo a ArrayAdapter utilizando el constructor del adaptador.

 mSOAdapter = new SearchOptionsAdapter(getActivity(), resultStrs, myViews); 

2- en getView:

 @Override public View getView(int position, View convertView, ViewGroup parent) { View view; ViewHolder viewHolder; if (!myViews.containsKey(position)) { viewHolder = new ViewHolder(); LayoutInflater inflater = LayoutInflater.from(getContext()); view = inflater.inflate(R.layout.search_options, parent, false); /// ...... YOUR CODE myViews.put(position, view); FontUtils.setCustomFontsIn(view, getContext().getAssets()); }else { view = myViews.get(position); } return view; } 

Por último, no más elementos de mezcla …

  • Cómo saber qué vista dentro de un elemento ListView específico al que se hizo clic
  • ListView no dispara setOnLongClickListener, sólo setOnItemClickListener
  • Android set listview height dinámicamente
  • Mostrar / Ocultar Listview SectionIndex on demand
  • ¿Los servicios del sistema no están disponibles para las actividades antes de crear?
  • Listview addFooterView problemas
  • Cómo crear ListView multinivel en Android
  • Android: AmazingListView encabezado fijado es intocable
  • Android listview semitransparente selección color de una fila
  • Android abriendo el menú contextual después de hacer clic en el botón
  • Listview / ExpandableListVer imágenes de contenido cuando se llama notifyDataSetChanged
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.