2011-01-01 13 views
5

L'obiettivo è implementare una Galleria il cui adattatore restituisce ListViews (in altre parole, scorrere verticalmente le ListViews incorporate in una Galleria che scorre orizzontalmente). Funziona dopo un po 'di lavoro, ma quando si tenta di scorrere orizzontalmente, ListView appare molto nervoso, come se vi fosse una certa aderenza al centro. Non ho osservato questo tipo di comportamento con nessun altro tipo di Vista incorporato in una Galleria.Incorporamento di ListView all'interno della Galleria

Ecco che cosa ho provato:

Inizialmente, ho scoperto che il ListView schiacciato eventi touch, così l'ascoltatore gesto sulla Galleria mai viene licenziato.

Così nel metodo onCreate() della attività, ho creato un GestureDetector:

galleryGestureDetector = new GestureDetector(this, gallery);

Poi, all'interno del metodo GetView() dell'adattatore Gallery, dopo che il ListView è stato gonfiato e configurato , ho qualche codice come questo:

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

In questo caso ho anche andato al passo estremo di restituire vero dal OnTouchListener per assicurarsi che il metodo onTouchEvent() della ListView è mai effettivamente chiamato. Lo stesso comportamento nervoso si verifica. Di conseguenza, penso di poter escludere le implementazioni in concorrenza su TouchEvent() tra le due viste.

Ho tentato di abusare anche del concetto TouchDelegate estendendo il rettangolo touch della galleria per includere ListView e quindi costringendo ListView a delegare ad esso, ma anche questo è stato uno sforzo inutile.

Mi piacerebbe alzare le mani e dire che non è possibile al momento, ma l'app Social Networking che include DroidX in qualche modo lo realizza!

+0

Probabilmente controllare che le viste della lista non stiano creando/gonfiando tonnellate di visualizzazioni ogni volta che la galleria viene renderizzata. Prova a memorizzarli nella cache (o semplicemente usando un singolo campo statico) solo per vedere se questo è il problema. – monkjack

+0

Monkjack di buon pensiero, e in effetti sembra che la Galleria stesse riciclando le ListViews restituite dal suo adattatore dopo che erano usciti dalla selezione. Ho provato a memorizzare nella cache le visualizzazioni come suggerivi e ho verificato che dei 3 elementi che sto usando per testare le soluzioni a questo problema sono stati gonfiati solo 3 visualizzazioni. Sfortunatamente, vedo lo stesso risultato ... Dopo che la vista scorre su una piccola quantità, inizia a tremare come un matto. – jkschneider

+0

Ancora più misterioso - Ho notato oggi che se continuo a provare a scorrere orizzontalmente dopo che ListView inizia a tremare, la Galleria a volte rimane bloccata tra due Visualizzazioni. – jkschneider

risposta

5

Il problema è che ListView intercetta gli eventi di tocco dalla Galleria e quindi modifica la posizione della vista stessa. Questo è ciò che porta all'effetto di jittering avanti e indietro che vedo quando utilizzo i widget così come sono. Considero questo un bug nel widget Galleria, ma nel frattempo può essere fissato dalla sottoclasse Galleria in questo modo:

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); 
} 

}

Se si utilizza BetterGallery al posto della Galleria, il tutto funziona bene!