2016-01-22 25 views
11

Contribuisco alla libreria open source e ho l'errore lint "Non trattare la posizione come fissa, utilizzare immediatamente e chiamare holder.getAdapterPosition () di guardare in su dopo" per questo codice:Errore filaccia "Non trattare la posizione come fisso, usare solo immediatamente ..."

@Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 
    mAdapter.onBindViewHolder(holder, position); 

    if (!isFirstOnly || position > mLastPosition) { 
     for (Animator anim : getAnimators(holder.itemView)) { 
     anim.setDuration(mDuration).start(); 
     anim.setInterpolator(mInterpolator); 
     } 
     mLastPosition = position; 
    } else { 
     ViewHelper.clear(holder.itemView); 
    } 
    } 

ho controllato che è perché la posizione viene salvato per l'uso futuro. È una domanda al creatore della biblioteca perché ha bisogno di questa logica. Ma problema è scomparso quando cambio l'utilizzo della posizione per l'utilizzo holder.getAdapterPosition():

@Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 
    mAdapter.onBindViewHolder(holder, position); 

    if (!isFirstOnly || holder.getAdapterPosition() > mLastPosition) { 
     for (Animator anim : getAnimators(holder.itemView)) { 
     anim.setDuration(mDuration).start(); 
     anim.setInterpolator(mInterpolator); 
     } 
     mLastPosition = holder.getAdapterPosition(); 
    } else { 
     ViewHelper.clear(holder.itemView); 
    } 
    } 

Suppongo che concettualmente non ha cambiato molto, ma non peloso è soddisfatto ora. Perché?

+1

Non vi è alcuna garanzia che il bind venga chiamato nell'ordine perfetto in cui le visualizzazioni degli articoli sono effettivamente visibili. Quindi, 'mLastPosition' potrebbe non essere l'ultimo elemento visibile. –

+1

Ok, questo è un buon input per i creatori di librerie, ma perché il lint è soddisfatto ora? –

risposta

18

La documentazione di RecyclerView.Adapter.onBindViewHolder() stati:

Si noti che diversamente ListView, RecyclerView non chiamerà questo metodo ancora una volta se la posizione dei cambiamenti elemento nel set di dati a meno che l'oggetto stesso viene invalidata o il nuovo la posizione non può essere determinata. Per questo motivo, è necessario utilizzare il parametro posizione solo mentre acquisisce l'elemento dati correlato all'interno di questo metodo e non è necessario mantenere una copia di tale valore su . Se avete bisogno della posizione di un oggetto in seguito (ad esempio in un click ascoltatore), utilizzare getAdapterPosition(), che avrà il aggiornata adattatore di posizione

Quindi, tecnicamente oggetti possono essere ri-arrangiati e vincolante non lo farà essere necessario perché gli articoli non sono ancora invalidati. La variabile position ricevuta è valida solo per l'ambito della funzione di collegamento e non punta sempre alla posizione corretta nel set di dati. Ecco perché la funzione getAdapterPosition() deve essere chiamata ogni volta che è necessaria la posizione aggiornata.

IMHO, mLastPosition = holder.getAdapterPosition(); è ancora potenzialmente sbagliato. Poiché l'articolo può essere riorganizzato e mLastPosition punta ancora alla posizione precedente.

Circa il motivo per cui la peluria è silenziosa, forse la regola di Lint non è così approfondita. Sta solo controllando se il parametro position viene copiato o meno.

+1

In realtà non funziona su linux build, ma passa su mac –

+4

Allora perché Google mette fuori esempi con codice che causerà questo errore? –

+0

Strano. Immagino che stiano progettando qualcosa. –