2011-01-01 19 views
5

El objetivo es implementar una galería cuyo adaptador devuelva ListViews (en otras palabras, desplazamiento vertical de ListViews incrustado en una galería de desplazamiento horizontal). De alguna manera funciona después de un poco de trabajo, pero cuando se intenta desplazar horizontalmente, el ListView se ve muy nervioso, como si hubiera algo de pegajoso al estar centrado. No he observado este tipo de comportamiento con ningún otro tipo de Vista incrustada en una Galería.Incrustar ListView dentro de la galería

Esto es lo que he intentado:

Inicialmente, me encontré con que el ListView aplastada eventos de toque, por lo que el oyente gesto en la galería no es despedido.

Así que en el método onCreate() de la actividad, he creado un GestureDetector:

galleryGestureDetector = new GestureDetector(this, gallery);

Entonces, dentro del método getView() del adaptador Galería, después de que el ListView se ha inflado y configurado , tengo algo de código como este:

listView.setOnTouchListener(new OnTouchListener() { 
    public boolean onTouch(View v, MotionEvent event) { 
     galleryGestureDetector.onTouchEvent(event); 
     return true; 
    } 
}); 

En este caso, incluso he ido a la medida extrema de retornar verdadero de lo OnTouchListener para asegurar que el método onTouchEvent() de la vista de lista no se llama en realidad. El mismo comportamiento nervioso ocurre. Como resultado, creo que puedo descartar competir en las implementaciones de TouchEvent() entre las dos vistas.

Intenté abusar del concepto TouchDelegate al extender el rectángulo táctil de la Galería para incluir el ListView y luego forzar el ListView para delegarlo, pero esto también fue un esfuerzo inútil.

¡Yo levantaría las manos y diría que no es posible actualmente, pero la aplicación de red social que viene con el DroidX de alguna manera lo logra!

+0

Quizás compruebe que sus vistas de lista no están creando/inflando toneladas de vistas cada vez que se representa la galería. Intente guardarlos en la memoria caché (o simplemente usando un solo campo estático) solo para ver si ese es el problema. – monkjack

+0

Bueno, pensó monkjack, y de hecho, parece que la Galería estaba reciclando las ListViews devueltas de su adaptador después de que salieran de la selección. Intenté almacenar en caché las vistas como sugirió y verifiqué que de los 3 elementos que estoy usando para probar soluciones a este problema, solo se han inflado 3 vistas. Desafortunadamente, veo el mismo resultado ... Después de que la vista se desliza en una pequeña cantidad, comienza a agitarse como loca. – jkschneider

+0

Aún más misterioso: hoy noté que si sigo intentando desplazarme horizontalmente después de que ListView comience a agitarse, la Galería a veces se quedará atascada entre dos Vistas. – jkschneider

Respuesta

5

El problema es que ListView está interceptando eventos táctiles de la Galería y luego alterando la posición de la vista. Esto es lo que lleva al efecto de jittering de ida y vuelta que veo cuando uso los widgets como están. Considero que esto es un error en la galería de widgets, pero mientras tanto se puede fijar subclasificando Galería de la siguiente manera:

public class BetterGallery extends Gallery { 
private boolean scrollingHorizontally = false; 

public BetterGallery(Context context, AttributeSet attrs, int defStyle) { 
    super(context, attrs, defStyle); 
} 

public BetterGallery(Context context, AttributeSet attrs) { 
    super(context, attrs); 
} 

public BetterGallery(Context context) { 
    super(context); 
} 

@Override 
public boolean onInterceptTouchEvent(MotionEvent ev) { 
    super.onInterceptTouchEvent(ev); 
    return scrollingHorizontally; 
} 

@Override 
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { 
    scrollingHorizontally = true; 
    return super.onScroll(e1, e2, distanceX, distanceY); 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    switch(event.getAction()) { 
    case MotionEvent.ACTION_UP: 
    case MotionEvent.ACTION_CANCEL: 
     scrollingHorizontally = false; 
    } 

    return super.onTouchEvent(event); 
} 

}

Si utiliza BetterGallery en lugar de la Galería, todo funciona igual ¡multa!

Cuestiones relacionadas