Pregunta

Tengo la siguiente estructura en mi aplicación:

Fragmentactividad con ViewPager manteniendo múltiples fragmentos administrados por FragmentStatePagerAdapter Uso de compativility paquete con Android 2.1

Cada fragmento contiene ListView. Cada elemento en el ListView tiene un LinearLayout con dos TextViews y un Button. los LinearLayout y el botón tiene onClickListeners (separado). Haciendo clic en el LinearLayout comienza otro Activity. Noté que el comportamiento de los clics es muy inconsistente: a veces la acción se ejecuta de inmediato, pero muy a menudo se retrasa y a veces se ignora sin importar cuántas veces aproveche. Se vuelve aún más extraño porque puedo tocar y la acción solo se ejecutará cuando comience a desplazar la lista. Probé varias combinaciones de setFocusable(false) y setSelectable(true) Pero parece no hacer ninguna diferencia. ¿Algunas ideas? Estaré encantado de proporcionar más detalles.

¿Fue útil?

Solución 3

En caso de que alguien se preguntó cómo resolví esto. Básicamente tuve que simplificar mis diseños. Parece que cuando tiene estructuras anidadas complejas, los eventos pueden tardar demasiado en burbujear y si comienza a desplazarse la lista al mismo tiempo, el evento puede desencadenar una acción incorrecta. Recorté los diseños cambiando a RelativeLaYOut tanto como sea posible y eso pareció ayudar mucho

Otros consejos

Tuve un problema similar y me tomó 2 días depurarlo y resolverlo. Tengo un ListAdapter que crea varias vistas de text en un LinealLayout para cada elemento de lista. Cada TextView tiene su propia OnClickListener, porque necesito manejar los clics en cada elemento.

Cuando cambié la implementación para reutilizar las opiniones, el OnClickListener dejó de funcionar correctamente. En 4.4.2 La mayoría de los clics funcionaban, pero a veces no hubo reacción hasta que me desplazé en la lista. En 2.3, los primeros clics no funcionarían y luego todos los clics donde se manejan en una explosión.

En mi caso especial, creé toda la vista en el código Java y no inflando los recursos. Y el punto crítico fue que establecí los PlayOutParams del LinearLayout incluso cuando se reutilizó la vista (esto parece ser más seguro y luego suponiendo que la vista reutilizada tiene los parámetros de diseño correctos). ¡Cuando no configure los PlayOutParams al reutilizar todo funciona bien! Aquí está el código crítico:

public View getView(int position, View convertView, ViewGroup parent) {
    LinearLayout tapeLine = null;
    if (convertView != null && convertView instanceof LinearLayout && ((LinearLayout)convertView).getChildCount() == 4) tapeLine = (LinearLayout) convertView; // Reuse view
    else tapeLine = new LinearLayout(activity);
    if (convertView == null) { // Don't set LayoutParams when reusing view
        ViewGroup.LayoutParams tapeLineLayoutParams = new AbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        tapeLine.setLayoutParams(tapeLineLayoutParams);
    }
    ScrollingTape scrollingTape = calculatorHolder.getCalculator().getScrollingTape();
    int tapeWidthPx = parent.getWidth();
    TapeLineTextSizeInfo tapeLineTextSizeInfo = calculatorHolder.getTapeLineTextSizeHelper().createTapeLineTextSizeInfo(tapeWidthPx);
    ScrollingTapeLine line = scrollingTape.getLine(position);
    tapeLine.setOrientation(LinearLayout.HORIZONTAL);
    int tapeBackgroundColor = getBackgroundColor(line);
    tapeLine.setBackgroundColor(tapeBackgroundColor);
    addColumnViews(tapeLine, line, tapeLineTextSizeInfo);
    tapeLine.setTag(R.id.scrollingtapeadapter_viewtag_position, position);
    tapeLine.setOnLongClickListener(longClickListener);
    tapeLine.setOnClickListener(remainClickListener);
    return tapeLine;
}

¿Cuál es el fondo de este extraño comportamiento de la vista de la lista? Hice un poco de depuración e investigación en las fuentes de Android. Cuando Android actualiza una vista, hay dos pasos importantes en la medición y la onlayout. El método GetView del ListAdapter no solo se llama para dibujar la vista, sino también antes durante la medición. En este caso posterior, se crea la vista, pero aún no está registrada en la cadena de eventos para manejar los eventos de clic.

Cuando una vista que se ha creado para OnMeASure se reutiliza más tarde para ser dibujada acutalmente en la pantalla, debe estar registrado desde el sistema Android para manejar los eventos de clic. Para este caso especial, los desarrolladores de Android habían hecho algo, que podría considerarse como un truco sucio. Se utiliza una bandera especial en LayoutParams para decidir que la vista debe estar registrada en el cambio de evento.

Ahora mi problema: al reiniciar los PlayOutParams también cuando se reutiliza una vista, esta bandera siempre se restableció. Por lo tanto, el sistema Android no registraría la vista y los eventos no llegarían.

Para resumir: al resusar una vista en GetView de un ListAdapter, no sobrescriba los LayoutParams porque mantienen información interna del sistema Android.

Me encontré con el mismo problema, pero en mi caso la solución no era mantener las referencias a las vistas, lo que causó problemas con el almacenamiento en caché de la vista de ListView. Después de implementar adecuadamente getView() Método Con el uso de Converview, todo comportamiento extraño con llamadas de clics perdidas / inesperadas se había ido.

Lo que funcionó para mí fue asignar un OnItemClickListener hacia ListView mediante setOnItemClickListener, en lugar de un OnClickListener a los elementos de la lista individual. Obviamente el botón todavía necesita su propio OnClickListener, pero no he probado ese escenario.

No estoy seguro de si esto ayuda a alguien, pero tuve un problema similar con una Tablelayout. Las soluciones anteriores no solucionan mi problema.

Para mí, el problema era:android:animateLayoutChanges="true"

Eliminar esto permitió que mis clics de botón dentro de mis filas de Tablelayout funcionen correctamente. Luego tuve que animar mis puntos de vista manualmente en lugar de confiar en la propiedad anterior.

Parece que está ejecutando algún proceso de bloqueo (como invocar WebServices o abrir archivos) en el hilo de eventos, por lo que su hilo de eventos está bloqueado. Si este es el caso, procese su código de bloqueo en otro hilo que el hilo del evento.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top