2010-01-22 5 views
10

Il codice seguente NON modifica il testo di tutte le righe ListView's perché getChildCount() non ottiene tutte le righe ListView's, ma solo le righe che sono visibili.In un ListView Android, come posso eseguire iterazioni/manipolare tutte le viste secondarie, non solo quelle visibili?

for (int i = 0; i < listView.getChildCount(); i++) 
{ 
    View v = listView.getChildAt(i); 
    TextView tx = (TextView) v.findViewById(R.id.mytext); 
    tx.setTextSize(newTextSize); 
} 

Quindi, cosa DEVO fare?

C'è un codice per ottenere una notifica quando una riga ListView's diventa visibile, quindi posso impostare la sua dimensione del testo, allora?

+0

Memorizza la dimensione del testo nell'adattatore o 'ListActivity' e imposta la dimensione del testo nel metodo' getView' dell'adattatore. –

risposta

9

List13 dalle demo API fa qualcosa di simile usando OnScrollStateChanged. Tuttavia, potrebbe esserci un modo migliore:

public void onScrollStateChanged(AbsListView view, int scrollState) { 
    switch (scrollState) { 
    case OnScrollListener.SCROLL_STATE_IDLE: 
     mBusy = false; 

     int first = view.getFirstVisiblePosition(); 
     int count = view.getChildCount(); 
     for (int i=0; i<count; i++) { 
      TextView t = (TextView)view.getChildAt(i); 
      if (t.getTag() != null) { 
       t.setText(mStrings[first + i]); 
       t.setTag(null); 
      } 
     } 

     mStatus.setText("Idle"); 
     break; 

. . .

modifica di Corey Trager:

È possibile che questo sicuramente mi ha segnalato nella giusta direzione. Ho trovato che la gestione di OnScrollListener.onScroll ha funzionato meglio di onScrollStateChanged. Anche se ho rimosso la dichiarazione case in onScrollSgtaetChanged e gestito ogni cambiamento di stato, alcuni testi non venivano ridimensionati. Ma con onScroll, le cose sembrano funzionare.

Quindi, il mio codice apparentemente di lavoro si presenta così:

public void onScroll(AbsListView v, int firstVisibleItem, int visibleCount, int totalItemCount) 
{ 
    ListView lv = this.getListView(); 
    int childCount = lv.getChildCount(); 

    for (int i = 0; i < childCount; i++) 
    { 
     View v = lv.getChildAt(i); 
     TextView tx = (TextView) v.findViewById(R.id.mytext); 
     tx.setTextSize(textSize); 
    } 
} 
+2

Probabilmente funzionerà, ma sarà anche molto molto costoso. Stai facendo lo stesso lavoro su ogni evento di scorrimento, di cui puoi ricevere molti (e non necessariamente solo quando un nuovo elemento diventa visibile.) –

+1

@Romain - "costoso" importa solo se c'è qualche effetto che l'utente stesso può vedere. E non c'è. I computer sono più veloci di quelli a cui danno credito e non si preoccupano del duro lavoro. Ehi, pensa a qualsiasi tipo di programma di pittura che reagisce a ogni evento di movimento del mouse estendendo il tratto visibile. –

+2

No, non lo sono. Abbiamo a che fare con i telefoni e * tutto * si fa a spese * della batteria *. Non c'è assolutamente alcuna ragione per essere un programmatore pigro e sprecare la batteria. Il motivo per cui Android è utilizzabile sui telefoni è perché passiamo molto tempo a preoccuparci delle prestazioni e della durata della batteria. Abbiamo ancora molto da fare ma il tuo punto di vista è sicuramente imperfetto. Ci sono situazioni in cui non c'è bisogno di preoccuparsi molto delle prestazioni (fare clic sul pulsante per esempio), ma fare ciò che si fa per ogni pixel scansionato è semplicemente stupido. –

15

in una lista i figli unici sono quelli visibili. Se vuoi fare qualcosa con "tutti i bambini", fallo nell'adattatore. Questo è il posto migliore.

+0

"tutti i bambini" indica le viste di testo. Sto cambiando la dimensione del carattere. I figli di TextViews dell'adattatore o figli della listview sono di per sé? –

+0

Sono figli di ListView. –

+0

questa è la risposta giusta. Ho scelto di sovrascrivere getView nel mio adattatore personalizzato ed eseguire il lavoro necessario per oggetto da visualizzare. inoltre, se il tuo testo viene modificato dall'evento onClick, chiama invalidateViews() nella visualizzazione elenco. Funziona bene! Grazie Romain! – bgs

0

Non sei sicuro dell'effetto performace ma puoi provarlo.

//declare the list 
ListView list = (ListView)findViewById(R.id.yourListID); 

// in my case i have spinners and made a test just to know if this works 
Spinner spnWhatever; 
View view; 
int i =0; 


     do{ 

      view =list.getAdapter().getView(i,null,null); 
      //get the spinners from each row 
      spnWhatever =(Spinner)view.findViewById(R.id.spnTarifas); 

     i++; 

     }while(list.getAdapter().getCount() !=i); 
Problemi correlati