2015-01-16 17 views
6

Ho un RecyclerView che contiene un numero di elementi. Ogni elemento è solo un TextView, ma lo stile del padding e del font può cambiare per ogni oggetto. In termini di scorrimento più efficiente/scorrevole, è meglio per me creare un file di layout separato per ciascuna variabile dell'elemento (es .: padding, stile del testo), oppure posso semplicemente impostare il padding e lo stile del testo per ogni oggetto a livello di programmazione quando viene recuperata la vista oggetto, senza doversi preoccupare di un impatto sulle prestazioni?ottimizzazione di RecyclerView/ListView

Grazie!

+0

Quanti tipi di vista è necessario utilizzare nell'elenco? –

+0

Lo farei a livello di programmazione. –

risposta

3

In breve, minore è il lavoro svolto nel metodo onBindViewHolder(), migliore è lo scorrimento della visualizzazione della lista.

L'implementazione più efficiente prende semplicemente i dati dal modello che viene passato e semplicemente li imposta al titolare della vista.

Poiché tutto questo lavoro nel metodo onBindViewHolder() viene eseguito sul thread dell'interfaccia utente, offendere qualsiasi lavoro aggiuntivo prima del binding o offloaded al thread anthoer è utile per elencare le prestazioni della visualizzazione.

Per esempio, consente di dire che avete una lista che contiene una serie di operazioni, come di seguito:

class Task { 
    Date dateDue; 
    String title; 
    String description; 

    // getters and setters here 
} 

Ogni attività ha un titolo, una descrizione e una data socio dovuta con esso. Come requisito per la tua app, se la data odierna è precedente alla data di scadenza, la riga deve essere verde e se ha superato la data di scadenza, dovrebbe essere rossa. Anche l'oggetto Task ad esso associato richiede alcune formattazioni speciali per la data prima di impostarlo sulla vista.

Ci sono due cose che si possono fare in questo onBindViewHolder() come ogni riga è resa sullo schermo:

  • Sarà necessario controllare la condizionale ogni data e confrontarlo contro la data di oggi
  • Sarà necessario applicare un programma di formattazione della data per ottenere la visualizzazione della data nella specifica richiesta:

es.

class MyRecyclerView.Adapter extends RecyclerView.Adapter { 

    static final TODAYS_DATE = new Date(); 
    static final DATE_FORMAT = new SimpleDateFormat("MM dd, yyyy"); 

    public onBindViewHolder(Task.ViewHolder tvh, int position) { 
     Task task = getItem(position); 

     if (TODAYS_DATE.compareTo(task.dateDue) > 0) { 
      tvh.backgroundView.setColor(Color.GREEN); 
     } else { 
      tvh.backgroundView.setColor(Color.RED); 
     } 

     String dueDateFormatted = DATE_FORMAT.format(task.getDateDue()); 
     tvh.dateTextView.setDate(dueDateFormatted); 
    } 
} 

In quanto sopra, per ogni riga visualizzata, viene eseguito un confronto di data. Mentre eravamo impegnati, ci siamo persino presi la libertà di rendere costante la data odierna: la creazione di oggetti è probabilmente una delle cose più costose che puoi fare in un onBindViewHolder() quindi qualsiasi ottimizzazione è apprezzata. Inoltre, la data passata nell'oggetto Task non era nel formato corretto, quindi è formattata anche al volo.

Anche se questo esempio è banale, questo può mollare rapidamente in modo da bloccare la vista elenco scorrendo verso l'interno di una scansione. Il modo migliore per farlo è passare un oggetto intermedio, ad esempio un modello di vista che rappresenta invece lo stato della vista anziché il modello di business effettivo.

Invece di passare il tuo Task come modello all'adattatore, creiamo un modello intermedio chiamato TaskViewModel che viene creato e impostato sull'adattatore. Ora prima di impostare qualsiasi informazione viene inviata alla scheda, tutto il lavoro è fatto prima che venga applicato qualsiasi rendering della vista.Ciò si traduce in un tempo di inizializzazione più lungo prima dell'invio dei dati al numero RecyclerView ma al migliore compromesso tra le prestazioni della visualizzazione elenco.

Questo modello vista invece potrebbe essere:

public class TaskViewModel { 
    int overdueColor; 
    String dateDue; 
} 

Ora, quando il compito di associare i dati alla vista, abbiamo lo stato di visualizzazione effettiva di essere rappresentati nel modello di vista e il nostro thread dell'interfaccia utente può continuare a essere Jank gratuito.

public onBindViewHolder(Task.ViewHolder tvh, int position) { 
    TaskViewModel taskViewModel = getItem(position); 
    tvh.backgroundView.setColor(taskViewModel.getOverdueColor()); 
    tvh.dateTextView.setDate(taskViewModel.getDateDue()); 
} 
+0

Grazie. Capisco il concetto che sta dietro al riciclaggio. La domanda che sto chiedendo di fare con il padding è più una questione di come ciascuna vista viene disegnata dal sistema. Se ogni volta che viene visualizzata la vista sullo schermo, se la vista richiede il riempimento iniziale, quindi, modificando il padding per ogni riga, non perderò le prestazioni. Se il padding è in qualche modo memorizzato nella cache, allora rischio un colpo di performance. –