2012-04-25 14 views
5

Ho un listView con un adattatore personalizzato. Quando succede qualcosa (un clic in un bambino) eseguo alcune operazioni di calcolo e modifica la vista figlio. SE alcune condizioni sono state soddisfatte, è necessario modificare l'altro bambino non correlato al bambino cliccato.A volte listView.getChildAt (int index) restituisce NULL (Android)

Questo a volte funziona, ma a volte non riesce e il DDMS dice che la vista è nullo ...

Lascia che ti mostri il codice:

 if(invalidaEste != -1) 
     { 
      try 
      { 
       View v = lv_data.getChildAt(invalidaEste); 
       if(v== null) 
       { 
        Log.e("MY_LOG", "SIZE " + lv_data.getCount()); 
        Log.e("MY_LOG", "IS_NULL " + String.valueOf(invalidaEste)); 
       } 

       if(invalidaEste >= lv_data.getFirstVisiblePosition() && 
        invalidaEste <= lv_data.getLastVisiblePosition()) 
       { 
        RelacionFacturaPago rpf = (RelacionFacturaPago)lv_data.getAdapter().getItem(invalidaEste); 
        TextView tv = (TextView)v.findViewById(R.id.tv_pendiente); 
        tv.setText(Formato.double2Screen(rpf.getPorPagar())); 
       } 
      } 
      catch (Exception e) 
      { 
       Log.e("MY_LOG", "FAIL"); 
       Log.e("MY_LOG", String.valueOf(invalidaEste)); 
      } 

     } 

invalidaEste è la vista che voglio modificare. Quando v è nullo Registro l'indice per verificare se è OK. Sempre è inferiore o uguale a listView.getCount()

Perché sta succedendo?

Altri dati: il codice si trova all'interno di onAnimationStart (Animazione animazione) di un listener AnimationListener.

+0

l'adattatore ha valori 'nulli'? – zapl

+0

possibile duplicato di [ListView getChildAt restituisce null per bambini visibili] (http://stackoverflow.com/questions/6766625/listview-getchildat-returning-null-for-visible-children) – rds

risposta

9

A causa del riciclaggio della vista, listView.getChildAt() restituirà solo una vista per le posizioni che sta visualizzando e forse un'altra. Forse se condividi più parti del tuo codice, possiamo aiutarti a capire come affrontare al meglio il problema.

+0

La vista nulla è una vista visibile. – Desenfoque

+1

mmm ... Credo di vedere il tuo punto ... Il problema si verifica quando la vista con indice 0 non è visibile ... Sto fraintendendo il metodo getChildAt() ... – Desenfoque

+0

È veramente rotto? Vedo che sei già questo controllo: 'if (invalidaEste> = lv_data.getFirstVisiblePosition() && invalidaEste <= lv_data.getLastVisiblePosition())', e qualsiasi altra vista dovrebbe essere aggiornata dall'adattatore quando lo si scorre in vista . – dmon

1

Se quel bambino non è visibile sullo schermo significa che non esiste una vista per esso. Credo che questo sia il tuo caso non funzionante.

È buona norma modificare i dati dietro l'adattatore di elenco e chiamare notifyDataSetChanged() sull'adattatore. Questo informerà l'elenco della scheda è cambiato e dipingere nuovamente le visualizzazioni.

Se si desidera aggiornare manualmente la visualizzazione, suppongo che l'unica soluzione sia quella di conservare i nuovi valori da qualche parte e attendere fino a quando la vista non diventa visibile. A quel punto hai un riferimento valido e puoi fare gli aggiornamenti.

+0

Grazie per la tua risposta .... Come puoi vedere nel codice, io uso la vista (v) solo quando l'indice appartiene a un elemento visibile. Non sto usando notifyDataSetChanged() perché annulla le animazioni in listView. – Desenfoque

+0

Vedo che hai il bambino quando invalidaEste! = -1. Questo non significa che sia un indice con vista visibile ma un indice che potrebbe essere buono. C'è del codice in cima a quello che volevi incollare e non è visibile? – azertiti

+0

invalidaEste! = -1 indica solo che è un indice valido. Io uso if (invalidaEste> = lv_data.getFirstVisiblePosition() && invalidaEste <= lv_data.getLastVisiblePosition()) per verificare se è visibile. – Desenfoque

4

Dmon e Azertiti sono entrambi corretti ... una volta scorsa la lista, ti troverai nei guai. Se la vista non è visibile, allora non esiste (cioè è stata riciclata da Android). Potrai ricostruire la vista una volta che è fatto scorrere in

fare qualcosa di simile dovrebbe funzionare:.

View view; 

int nFirstPos = lv_data.getFirstVisiblePosition(); 
int nWantedPos = invalidaEste - nFirstPos; 

if ((nWantedPos >= 0) && (nWantedPos <= lv_data.getChildCount()) 
{ 
view = lv_data.getChildAt(nWantedPos); 
if (view == null) 
    return; 
// else we have the view we want 
} 
1

provo con una riga di codice, quando ho bisogno di andare in una posizione valida di un Visualizzazione elenco. ecco le tue variabili usate come esempio. dove lv_data è il ListView e tv è il tuo TextView.

if (lv_data.getChildAt(lv_data.getPositionForView(tv)) != null) { 
    int position = lv_data.getPositionForView(tv); 
} 
Problemi correlati