2015-04-11 22 views
8

Ich habe einen RecyclerView mit Karten als primären Viewtyp erstellt. Was ich versuche zu erreichen, ist, dass, wenn der Benutzer auf ein Element klickt, der ViewType dieses Elements von den Karten zu einem anderen Viewtyp geändert wird (zum Beispiel eine Liste Textansichten, die horizontal scrollbar sind).So ändern Sie den ViewType eines RecyclerView-Elements onClick

Mein Code für RecyclerView Adapter ist wie folgt:

Im unteren Teil des Codes ich eine arrraylist von Enum-Typen erstellt haben Spur des angeklickten Zustand jeder Zeile in recyclerview zu halten, dann habe ich die Größe meine Daten-Set und meine Arraylist für jede Zeile mit SHOW_PRIMARY_CONTENT initialisiert

public class DisplayItemsAdapter extends RecyclerView.Adapter<DisplayItemsAdapter.ViewHolder> { 

private static ArrayList<clickedState> itemClickedState; 
private enum clickedState { 
    SHOW_PRIMARY_CONTENT, 
    SHOW_SECONDARY_CONTENT 
} 

private ArrayList<ItemData> mDataset = new ArrayList<>(); 

public DisplayItemsAdapter(ArrayList<ItemData> dataset) { 
    mDataset = dataset; 
    itemClickedState = new ArrayList<>(); 
    for (int i = 0; i < mDataset.size(); i++) { 
     itemClickedState.add(i, clickedState.SHOW_PRIMARY_CONTENT); 
    } 
} 

Unten ist mein ViewHolder Klasse, die Verweise auf alle mein Kind Blick hält, es Implementiert View.OnClickListener. Warum es View.OnClickListener implementiert, ist so, dass es zwischen angeklickten Zuständen wechseln kann, um ViewTypes entsprechend zu ändern.

public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 

    TextView tvItemName; 
    TextView tvItemNumber; 

    public ViewHolder(View itemView) { 
     super(itemView); 

     tvItemName = (TextView) itemView.findViewById(R.id.tvItemName); 
     tvItemNumber = (TextView) itemView.findViewById(R.id.tvItemNumber); 

     tvTicketClass = (TextView) itemView.findViewById(R.id.tvTicketClass); 
    } 

    @Override 
    public void onClick(View v) { 
     itemClickedState.add(getAdapterPosition(), clickedState.SHOW_SECONDARY_CONTENT); 
    } 
} 

Dies ist, wo ich den Wert von Viewtype bin immer wieder von getItemViewType und Layout

@Override 
public DisplayItemsAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { 
    View v1 = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.display_Items_row, viewGroup, false); 
    View v2 = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.display_Items_ticket_class, viewGroup, false); 
    if (viewType == 0) { 
     return new ViewHolder(v1); 
    } else { 
     return new ViewHolder(v2); 
    } 
} 

ich die Ansichten mit Werten m Bindung Dann hier aufgeblasen Zurückkehren nach dem Viewtype von dem viewholderusing viewholder zurückgegeben. getItemViewType

@Override 
public void onBindViewHolder(DisplayItemsAdapter.ViewHolder viewHolder, final int position) { 
    if (viewHolder.getItemViewType() == 0) { 
     viewHolder.tvItemName.setText(mDataset.get(position).strItemName); 
     viewHolder.tvItemNumber.setText(mDataset.get(position).strItemNumber); 
    } else if (viewHolder.getItemViewType() == 1) { 
     for (int i = 0; i < mDataset.get(position).strClass.length; i++) { 
      viewHolder.tvTicketClass.setText(mDataset.get(position).strClass[i]); 
     } 
    } 
} 

@Override 
public int getItemCount() { 
    return mDataset.size(); 
} 

Und schließlich meine getItemViewType Logik

@Override 
public int getItemViewType(int position) { 
    if (itemClickedState.get(position) == clickedState.SHOW_SECONDARY_CONTENT) 
     return 1; 
    return 0; 
} 
} 

Was ich nicht verstehen konnte ist, dass, warum nicht etwas angezeigt wird, wenn ich den Code ausführen, scheint alles für mich gültig. Hilf mir !!!!

Antwort

4

siehe mein Beispiel:

// RecycleItemObject.java 
public class RecycleItemObject { 
     public static int LAYOUT_ITEM_PORTRAIN = 0; 
     public static int LAYOUT_ITEM_LANDSCAPE = 1; 
     private int type; 
     .................... 
     /** 
     * @return get layout type of item 
     */ 
     public int getType() { 
     return type; 
     } 

     /** 
     * set layout type of item 
     * @param type 
     */ 
     public void setType(int type) { 
     this.type = type; 
     } 
    } 

// adapter 
public Holder onCreateViewHolder(ViewGroup parent, int viewType) { 
    View view; 
    if (viewType == RecycleItemObject.LAYOUT_ITEM_PORTRAIN) { 
     view = LayoutInflater.from(context).inflate(R.layout.item_recycle_view_main, parent, false); 
    } else { 
     view = LayoutInflater.from(context).inflate(R.layout.item_recycle_view_main_land, parent, false); 
    } 
} 

// event click item 
@onClick.... 
curentObject.setType(RecycleItemObject.LAYOUT_ITEM_LANDSCAPE); 
// notify item only 
notifyItemChanged(itemPosition); 

bei mir ist es

2

Hoffe, dass Sie Ihr Problem herausgefunden haben, gut funktionieren. Wenn nicht, dann habe ich es für dich getan. Der Buggy Linie ist

@Override 
    public void onClick(View v) { 
     itemClickedState.add(getAdapterPosition(), clickedState.SHOW_SECONDARY_CONTENT); 
    } 

hier, was Sie tun, ist ein neues Element zu

Zugabe
itemClickedState.add(getAdapterPosition(), clickedState.SHOW_SECONDARY_CONTENT); 

Dies wird ein neues Objekt einfügen und die Größe mdataList und itemClickState unterscheidet und daher geschieht Fehlanpassung.

Verwenden Sie stattdessen itemClickedState.set(getAdapterPosition(), clickedState.SHOW_SECONDARY_CONTENT); . Und zweitens verstehe ich nicht was tvTicketClass ist. Wenn es sich um ein einzelnes TextView handelt, sollten Sie zuerst die Zeichenfolge verketten und sie tun tvTicketClass.settext(concatenatedstrClass). Hoffe, dass Sie von diesem Beitrag geholfen werden. Wenn Sie ein weiteres Problem haben, kommentieren Sie bitte.