Entonces tengo este problema que tenía antes, y naturalmente pedí ayuda aquí . La respuesta de Luksprog fue excelente porque no tenía idea de cómo ListView y GridView se optimizaban con vistas de reciclaje. Entonces, con su consejo, pude cambiar la forma en que agregué Vistas a mi GridView. El problema es que ahora tengo algo que no tiene sentido. Este es mi getView
de mi BaseAdapter
:
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
convertView = inflater.inflate(R.layout.day_view_item, parent, false);
}
Log.d("DayViewActivity", "Position is: "+position);
((TextView)convertView.findViewById(R.id.day_hour_side)).setText(array[position]);
LinearLayout layout = (LinearLayout)convertView.findViewById(R.id.day_event_layout);
//layout.addView(new EventFrame(parent.getContext()));
TextView create = new TextView(DayViewActivity.this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 62, getResources().getDisplayMetrics()), 1.0f);
params.topMargin = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
params.bottomMargin = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics());
create.setLayoutParams(params);
create.setBackgroundColor(Color.BLUE);
create.setText("Test");
//the following is my original LinearLayout.LayoutParams for correctly setting the TextView Height
//new LinearLayout.LayoutParams(0, (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 60, getResources().getDisplayMetrics()), 1.0f)
if(position == 0) {
Log.d("DayViewActivity", "This should only be running when position is 0. The position is: "+position);
layout.addView(create);
}
return convertView;
}
}
El problema es cuando me desplazo, esto sucede, y no en la posición 0 ... Parece la posición 6 y la posición 8, además pone dos en la posición 8. Ahora todavía estoy tratando de acostumbrarme a usar ListView y GridView, así que lo hago No entiendo por qué está sucediendo esto. Una de las principales razones por las que estoy haciendo esta pregunta es para ayudar a otros que probablemente no saben sobre ListView y la Vista de reciclaje de GridView, o la forma en que este artículo lo expresa, el mecanismo ScrapView.
Editar más tarde
Agregar un enlace a una charla de Google IO que es básicamente todo lo que necesita para comprender cómo funciona ListView. Link estaba muerto en uno de los comentarios. Entonces user3427079 fue lo suficientemente agradable como para actualizar ese enlace. Aquí es de fácil acceso.
0
).ListView
necesite una nueva fila para mostrar (como continuar desplazándose hacia abajo / arriba). El problema es que la vista que acaba de desaparecer y que se utilizará en las futuras posiciones necesariasTextView
ya se ha agregado, este es el problema. Para resolverlo, debe eliminarlo en elgetView
método sigetView
se llama al método para cualquier otra posición que no sea0
.Respuestas:
Inicialmente, tampoco tenía conocimiento del reciclaje de la vista de lista y el mecanismo de uso de conversión, pero después de una investigación de días enteros, entiendo bastante los mecanismos de la vista de lista al referirme a una imagen de android.amberfog
Cada vez que su vista de lista se llena con un adaptador, básicamente muestra el número de filas que la vista de lista puede mostrar en la pantalla y el número de filas no aumenta incluso cuando se desplaza por la lista. Este es el truco que usa Android para que la vista de lista funcione de manera más eficiente y rápida. Ahora, la historia interna de la vista de lista que se refiere a la imagen, como puede ver, inicialmente la vista de lista tiene 7 elementos visibles, luego, si se desplaza hacia arriba hasta que el elemento 1 ya no sea visible, getView () pasa esta vista (es decir, elemento1) a reciclador y puedes usar
dentro de tu
Notará en su logcat, inicialmente, convertview es nulo para todas las filas visibles, porque inicialmente no había vistas (es decir, elementos) en el reciclador, por lo que getView () crea una nueva vista para cada uno de los elementos visibles, pero el en el momento en que se desplaza hacia arriba y el elemento 1 se mueve fuera de la pantalla, se enviará al Reciclador con su estado actual (por ejemplo, el 'texto' de TextView o, en el caso mío, si la casilla de verificación está marcada, se asociará con la vista y almacenado en reciclador).
Ahora, cuando se desplaza hacia arriba / abajo, su vista de lista no creará una nueva vista, utilizará la vista que está en su reciclador. En su Logcat notará que el 'convertView' no es nulo, es porque su nuevo elemento 8 se dibujará utilizando convertview, es decir, básicamente toma la vista del elemento 1 del reciclador e infla el elemento 8 en su lugar, y puede observar eso en mi código. Si tenía una casilla de verificación y la marca en la posición 0 (digamos que el elemento 1 tenía una casilla de verificación y la marcó), de modo que cuando se desplace hacia abajo verá la casilla de verificación del elemento 8 ya marcada, esta es la razón por la que la vista de lista vuelve a utilizar la misma vista, no crea una nueva para usted debido a la optimización del rendimiento.
Cosas importantes
1 . Nunca fije la
layout_height
ylayout_width
de la vista de lista parawrap_content
quegetView()
obligará a su adaptador para obtener algún niño para medir la altura de los puntos de vista que se elaborará en la vista de lista y puede causar un comportamiento inesperado como volver convertview aunque la lista no es scrolled.always utilizanmatch_parent
o fijos ancho / alto.2 . Si desea utilizar un diseño o una vista después de la vista de lista, puede que le surja una pregunta si configuro la vista después de
layout_height
quefill_parent
la vista de lista no se muestre a medida que avanza por la pantalla, por lo que es mejor colocar su vista de lista dentro de un Por ejemplo, Diseño lineal y establezca la altura y el ancho de ese diseño según sus requisitos y haga que el atributo de alto y ancho de su vista de lista sea como su diseño (como si su ancho de diseño es 320 y la altura es 280), entonces su vista de lista debe tener la misma altura y ancho. Esto le indicará a getView () la altura y el ancho exactos de las vistas que se representarán, y getView () no llamará una y otra vez algunas filas aleatorias, y otros problemas como devolver la vista de conversión incluso antes de que el desplazamiento no ocurra, tengo prueba esto mismo, a menos que mi vista de lista estuviera dentro de lineaLayout, también tenía problemas como repetir la llamada de vista y convertir la vista, ya que poner Listview dentro de LinearLayout funcionó como magia para mí (no sabía por qué)Pero ahora está resuelto, lo sé, no soy tan bueno para explicar, pero como puse todo mi día en entender, pensé que otros principiantes como yo pueden obtener ayuda de mi experiencia y espero que ahora ustedes tengan un poco de comprensión. de ListView framework cómo funciona, ya que es realmente desordenado y complicado, por lo que los principiantes encontraron demasiados problemas para entenderlo
fuente
if you had a checkbox and if you check it at position 0(let say item1 has also a checkbox and you checked it) so when you scroll down you will see item 8 checkbox is already checked,this is why listview is re using the same view not creating a new for you due to performance optimization.
para que me diera cuenta de mi error. ¡La mejor publicación sobre el reciclaje de Android ListView que encontré!RecyclerView
funciona también en el mismo mecanismo? En mi pregunta stackoverflow.com/questions/47897770/… , sé que la tarea es silenciosa imposiblelistView
. ¿Debo probar conrecyclerView
?Tenga cuidado, en el patrón Titular, si establece la posición en su objeto Titular, debe establecerla cada vez, por ejemplo:
Este es un ejemplo de una clase abstracta, donde
realiza todas las operaciones de configuración para el
fuente
parent.setTag(holder);
en lugar de la forma correcta que es,view.setTag(holder);
Usando el patrón Holder puedes lograr lo que quieres:
Puede encontrar la descripción de este patrón aquí:
El reciclaje de la vista de lista ocurre cuando se desplaza hacia abajo en la pantalla y los elementos de la vista de lista anteriores están ocultos. Se reutilizan para mostrar nuevos elementos de vista de lista.
fuente