2015-09-01 11 views
12

voglio aggiungere l'extra TextView alla voce del RecyclerView.Adapter sulla base del ModalObject inviato al RecyclerView.AdapterAggiungere una vista dinamicamente alla voce del RecyclerView

Esempio:

Ho avuto un modale oggetto con variabile isAddText. In onCreateViewHolder verrà creato l'oggetto Holder con l'invio di itemView come parametro.

@Override 
public SolventViewHolders onCreateViewHolder(ViewGroup parent, int viewType) { 
    View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.solvent_list, null); 
    SolventViewHolders rcv = new SolventViewHolders(layoutView); 
    return rcv; 
} 

SolventViewHolders.java

public SolventViewHolders(View itemView) { 
    super(itemView); 
    itemView.setOnClickListener(this); 
    textView = (TextView) itemView.findViewById(R.id.country_name); 
    imageView = (ImageView) itemView.findViewById(R.id.country_photo); 
    // Now i need add a view to the itemView parent based on ModalObject isAddView property and how to do that. 
} 
+0

È possibile aggiungere una vista testuale nel layout e, in base alle proprie condizioni, renderlo visibile/invisibile. – vishalk

+0

Non voglio così..perché contiene più viste e dipendenze – user3607798

risposta

16

Il problema

Normalmente, si avrebbe bisogno di eseguire itemView.addView (vista, layoutParams) per aggiungere un'altra vista programmaticamente al layout, ma cosa con ViewHolders è, saranno riciclati da RecyclerView per collegare diversi elementi dall'adattatore, quindi non puoi farlo o questo nuovo TextView che desideri aggiungere apparirà quando un altro oggetto sarà associato a questa istanza viewHolder.

Mi vengono in mente un paio di modi per raggiungere il tuo obiettivo:


1. Passare del View visibilità

Il primo modo è quello di aggiungere questo textView per il layout e avere la sua visibilità GONE di default, e impostarlo su visibile quando vincolante che un elemento avete bisogno di questo per TextView, come ad esempio:

@Override 
public void onBindViewHolder(AbstractViewHolder holder, int position) { 
    holder.extraTextView.setVisibility(View.GONE); 
    if(shouldShowExtraTextView) { 
     holder.extraTextView.setVisibility(View.VISIBLE); 
     holder.extraTextView.setText(/* your text */); 
    } 
    // proceed to bind item to holder 
} 

2. Implementare diverse ViewHolders

Il secondo modo è più elegante, comporta la creazione di diversi tipi di ViewHolder. Per prima cosa è necessario creare costanti int per i due tipi di vista che devono essere visualizzati da RecyclerView. Posizionare l'adattatore il seguente codice:

private static final int VIEW_ORDINARY = 0; 
private static final int VIEW_WITH_EXTRA_TEXT_VIEW = 1; 

quindi implementare il getItemViewType (int position) Metodo dell'adattatore:

@Override 
public int getItemViewType(int position) { 
    if(position == /* position of item that needs extra text view */) { 
     return VIEW_WITH_EXTRA_TEXT_VIEW; 
    } else { 
     return VIEW_ORDINARY; 
    } 
} 

passo successivo è quello di creare Holder diverso a seconda del tipo restituito:

@Override 
public SolventViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    if(viewType == VIEW_WITH_EXTRA_TEXT_VIEW) { 
     View itemView = LayoutInflater.from(parent.getContext()) 
             .inflate(R.layout.solvent_list_with_extra_text_view, parent, false); 
     return new SolventViewHolderWithExtraTextView(itemView); 
    } else { 
     View itemView = LayoutInflater.from(parent.getContext()) 
             .inflate(R.layout.solvent_list, parent, false); 
     return new SolventViewHolder(itemView); 
    } 
} 

Naturalmente è necessario definire SolventViewHolderWithExtraTextView:

class SolventViewHolderWithExtraTextView extends SolventViewHolder { 
    TextView extraTextView; 

    public SolventViewHolderWithExtraTextView(View itemView) { 
     super(itemView); 
     this.extraTextView = (TextView) findViewById(R.id.extra_text_view); 
    } 
} 

E poi nel onBindViewHolder():

@Override 
public void onBindViewHolder(SolventViewHolder holder, int position) { 
    // you can use inheritance to handle binding logic or check the item view type again: 
    // bind ordinary view 
    if(getItemViewType(position)) { 
     // bind the extra textView 
     ((SolventViewHolderWithExtraTextView)holder).extraTextView.setText("I hope this works"); 
    } 
} 

In questo modo si dispone di un altro tipo di ViewHolder per gli elementi che hanno bisogno di un altro TextView, e sarà riutilizzato all'interno di tale categoria. È un modo preferito per fare ciò che vuoi.


3.Aggiungi/Rimuovi Visualizza in modo dinamico

Un'altra risposta (che è davvero brutto soluzione se mi chiedete) è quello di aggiungere e rimuovere vista dinamico, come ad esempio:

@Override 
public void onBindViewHolder(AbstractViewHolder holder, int position) { 
    if(shouldDisplayExtraTextView) { 
     if(!holder.displaysExtraTextView() { 
      holder.addExtraTextView(); 
     } 
     holder.extraTextView.setText("This solution is really ugly"); 
     } else { 
     if(holder.displaysExtraTextView() { 
      holder.removeExtraTextView(); 
     } 
    } 
} 

class SolventViewHolders extends RecyclerView.ViewHolder { 
    TextView extraTextView; 
    boolean viewAdded = false; 

    public SolventViewHolders(View itemView) { 
     super(itemView); 
     itemView.setOnClickListener(this); 
     textView = (TextView) itemView.findViewById(R.id.country_name); 
     imageView = (ImageView) itemView.findViewById(R.id.country_photo); 
     // Now i need add a view to the itemView parent based on ModalObject isAddView property and how to do that. 

     extraTextView = new TextView(); 
} 

public void addExtraTextView() { 
    ((ViewGroup)itemView).addView(extraTextView, layoutParams); 
    viewAdded = true; 
} 

public void removeExtraTextView() { 
    ((ViewGroup)itemView).removeView(extraTextView); 
    viewAdded = false; 
} 

public boolean displaysExtraTextView() { 
    return viewAdded; 
} 

Questo è veramente brutto, perché da aggiungere al fine di itemView devi lanciarlo su ViewGroup (che non deve essere necessariamente), quindi assicurati che sia sempre un ViewGroup o la sua sottoclasse. Inoltre, è necessario fornire layoutParam corretti per aggiungere la vista extraText a itemView.

+0

Non voglio gonfiare i layout, l'unico modo per me di aggiungere le viste dinamicamente. – user3607798

+0

Ho modificato la mia risposta per includere un altro modo per ottenere quello che vuoi, anche se non è una soluzione elegante, ma se per qualche motivo, come dici tu, non puoi gonfiare un altro layout, questo dovrebbe fare il trucco. – maciekjanusz

+0

@invariant Che cosa succede se un layout (vista) ha un pulsante e l'altro no, supponendo che il pulsante abbia implementato l'evento OnClick? – Journey

0

È inoltre possibile impostare itemView.setHasTransientState(true) in tal caso la vista non verrà riciclata fino a quando setHasTransientState è impostato su false.

Problemi correlati