2015-12-31 11 views
15

Aggiungo dinamicamente le viste ai miei articoli in un RecyclerView. Queste viste aggiunte dovrebbero essere solo correlate all'elemento a cui sono state aggiunte, ma sto riscontrando un problema durante lo scorrimento. Sembra che lo View venga riciclato e venga caricato un nuovo oggetto, ma quelle viste aggiunte in precedenza sono ancora lì, solo ora sull'elemento sbagliato.Aggiunta dinamica di viste in un RecyclerView solo all'elemento corrente

Suppongo che sia solo perché il ViewHolder viene riutilizzato, quindi gli elementi aggiunti vengono visualizzati di nuovo con un nuovo elemento, una volta caricati.

Come si può risolvere?

+0

si prega di condividere il codice classe adattatore –

+0

Solo per cancellare si aggiungono gli elementi dinamicamente a recyclerView o aggiungere nuove viste e popolarlo con i dati dinamicamente? –

+0

@CQM qualsiasi risposta sul mio commento sopra? –

risposta

3

Questa era una mia vecchia domanda. Vi è stata assegnata una taglia, quindi l'aumento di popolarità e le risposte multiple nuove e irrilevanti.

Come indicato in entrambe mio commento a this answer e commento @CQM s' sotto la mia domanda iniziale, la risposta è di eseguire l'override del metodo onViewRecycled() ed eseguire tutte le operazioni necessarie lì. Questo metodo viene chiamato quando una vista viene riciclata e qualsiasi operazione di pulizia può essere eseguita qui.

È possibile trovare la documentazione su questo metodo here.

Nel mio caso, si trattava di eliminare l'invisibile TextView collegato alla vista. Il testo stesso era stato cancellato, ma la vista rimaneva. Se molti invisibili TextView si accumulano sulla vista e non vengono riciclati correttamente durante lo scorrimento, lo scorrimento inizia a rallentare.

3

È necessario tenere traccia di quali viste sono state aggiunte in base ai dati di backup. Probabilmente aggiungerei eventuali visualizzazioni aggiuntive necessarie in onBindViewHolder() e rimuovere qualsiasi cosa che potrebbe essere presente in onViewRecycled(). Quindi, quando vuoi far apparire uno in modo dinamico, cambia la variabile che hai tracciato, se deve essere visibile, e chiama notifyItemChanged().

+1

Così ho implementato 'onViewRecycled' e sto attualmente eseguendo il ciclo di tutti i layout figlio nel layout che aggiungo anche le nuove viste, e poi controllando tramite' instanceof' se sono il tipo di vista che devo rimuovere e rimuovendoli se è così. C'è un modo più semplice per rimuovere tutti i tipi di una vista da un viewgroup? Inoltre, non sono proprio sicuro di cosa intendessi con la tua ultima frase. Sto attualmente aggiungendo nuove viste in 'onBindViewHolder' dato che i dati per ogni nuova vista sono contenuti nel mio elenco di dati. Non posso semplicemente attivare la visibilità delle viste perché aggiungo loro dinamicamente. – Orbit

1

Salva informazioni per tag per gli elementi con nuovo figlio ogni volta che si verifica l'operazione Aggiungi nuova visualizzazione. (In caso di preferenza condivisa, ad esempio) Tag: crea con posizione articolo su BindViewHolder.

... 
SharedPreference sharedPref = getSharedPreference("text" + position, context); 
SharedPreference.Editor editor = sharedPref.edit(); 
editor.putString("view", "ImageView"); 
... 

quando carico Adapter ottiene questo valore e inserisce come valore predefinito. Non sono sicuro della sua efficienza, ma lavorerò.

... 
String viewType = sharedPref.getString("view", null); 
//it will return ImageView 

se si conoscono alcune possibili viewTypes ad esempio andando sempre di essere ImageView & TextView quindi con una certa istruzione if che sarà ok.

if(viewType.equals("ImageVIew")){ 
item(position).addView(new ImageVIew(context)); 
} 

Good Luck

+0

Non farlo. Accederai e conserverai le preferenze condivise molto rapidamente durante lo scorrimento. – Orbit

3

Sulla base di questo:

ma quelle viste precedentemente aggiunti sono ancora lì, ma d'ora in poi l'articolo sbagliato.

In sostanza, secondo la documentazione RecyclerView, è necessario ripristinare il punto di vista ogni volta che all'interno del metodo onBindViewHolder(),

quindi cerchiamo dire, si dispone di un metodo che imposta un vista param se il tuo profilo, così il codice per lo stesso va come segue,

if (list.get(position).getId()==PreferenceManager.getUserID()) 
{ 
    // do some view change here 
setViewParam(true); 
}else 
{ 
    // reset the view change here 
setViewParam(false); 
} 

Allora, cosa stai facendo qui sta dando riciclato ViewHolder la possibilità di resettare. Commenta se hai bisogno di aiuto!

0

Nella classe adattatore del vostro recyclerView, nel metodo onBindViewHolder, creare un altro adattatore e fare gli stessi metodi per il vostro nuovo adattatore.

La gerarchia sarà,

mainRecyclerView -> ITEM1 (-> childRecyclerView1), item2 (-> childRecyclerView2), item3 (-> childRecyclerView3)

questo modo è possibile ottenere ciò che vuoi senza valori sbagliati per essere visualizzato su oggetti sbagliati.

4

È possibile utilizzare questo! setItemViewCacheSize(int size) Controlla qui RecyclerViewDocumentation.

La cache vista fuori campo rimane consapevoli dei cambiamenti nel adattatore collegato, permettendo una LayoutManager di riutilizzare quelle viste modificate senza dover restituire all'adattatore per riassociare loro.

0

Si dovrebbe prendere qualsiasi layout vuote come Linearlayout nel vostro bambino Elemento della XML e quindi aggiungere viste in quella LinearLayout della vostra particolare elemento in questo modo quando si scorre Lista tutti voi bambino di vista che sono stati aggiunti a LinearLayout anche scorrere con quell'elemento.

1

Prima di tutto, puoi condividere qualche altro codice per favore?

In secondo luogo, perché vorresti aggiungere dinamicamente nuove viste al volo? Perché non usi VIEWTYPE diversi o hai solo quelle viste già sul tuo layout e le rendi visibili/invisibili o visibili/perdute? (Credo che sarà più efficiente in questo modo).

Lasciami ricordare qualcosa su RecyclerView, sì quando l'utente sta scorrendo viewHolder viene riutilizzato (alcuni di essi possono essere creati, anche più del necessario per riempire lo schermo). Quindi, se è successo che hai aggiunto alcune visualizzazioni su "elemento A" e l'utente scorre su "elemento Z", quella viewHolder può essere riutilizzata per quella "voce Z", quindi la visualizzazione delle viste aggiunte in precedenza.

Come puoi risolvere quello?

Controllare sempre ogni articolo se è necessario aggiungere nuove viste, se sì aggiungerle se non sono già state aggiunte, altrimenti rimuovere sempre quelle viste (se presenti) per tornare allo stato di default viewHolder (o qualsiasi altra cosa si chiami).

Spero che questo ti possa aiutare.

Problemi correlati