2017-01-11 9 views
0

Ich bin mit folgender Situation konfrontiert: Ich habe einen RecyclerView mit 3 verschiedenen Viewtypen. Jeder enthält einen Untertitel und dann entweder eine Radiogruppe, Checkboxen oder einen EditText. Das Problem ist: Die Anzahl der Elemente (Edittext, Checkbox, Radiobuttons) ist variabel, daher kann ich keine statische Vorlage als Viewtypes erstellen. Also versuche ich etwas zu erreichen (Beispiel mit Radiobuttons):RecyclerView - Listeneintrag mit unbekannter Anzahl von Elementen

LISTVIEW 
------------------ 
row1 
     1) choice1 
     2) choice2 
------------------ 
row2 
     1) choice1 
     2) choice2 
     3) choice3 
------------------ 
row3 
     1) choice1 
------------------- 

Irgendwelche Ideen über einen guten Ansatz? Danke für deine Zeit und Hilfe! :)

EDIT: ChaitanyaAtkuris Antwort war sehr hilfreich, aber ich bekomme eine ClassCastException in der onBindViewHolder(). Es sagt "kann TitleHolder zu InputHolder nicht werfen" ... aber ich kann nicht herausfinden, warum das Halter-Objekt tatsächlich ein TitleHolder ist, weil es den richtigen Fall (INPUT) obwohl verwendet. Hier ist mein Adapter Code

public class RecAdapter extends RecyclerView.Adapter { 

private List<Object> items; 
private final int TITLE_VIEW = 0; 
private final int RADIO_GROUP = 1; 
private final int CHECK_BOX = 2; 
private final int INPUT = 3; 

public RecAdapter(List<Object> data) { 
    this.items = data; 
} 

@Override 
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
    RecyclerView.ViewHolder viewHolder = null; 
    LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 

    switch (viewType) { 
     case CHECK_BOX: 
      View v1 = inflater.inflate(R.layout.child_checkbox, parent, false); 
      viewHolder = new CheckboxHolder(v1); 
      break; 
     case TITLE_VIEW: 
      View v2 = inflater.inflate(R.layout.child_title, parent, false); 
      viewHolder = new TitleHolder(v2); 
      break; 
     case INPUT: 
      View v3 = inflater.inflate(R.layout.child_inputfield, parent, false); 
      viewHolder = new TitleHolder(v3); 
      break; 

    } 

    return viewHolder; 
} 

@Override 
public int getItemViewType(int position) { 
    ListItem item = (ListItem) items.get(position); 
    if (item.getviewType()==TITLE_VIEW) { 
     return TITLE_VIEW; 
    } else if (item.getviewType()==RADIO_GROUP) { 
     return RADIO_GROUP; 
    } else if (item.getviewType()==CHECK_BOX) { 
     return CHECK_BOX; 
    } else if (item.getviewType()==INPUT) { 
     return INPUT; 
    } 
     return -1; 
} 

@Override 
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 
    switch (holder.getItemViewType()) { 
     case CHECK_BOX: 
      CheckboxHolder checkboxHolder = (CheckboxHolder) holder; 
      configureCheckBoxHolder(checkboxHolder, position); 
      break; 
     case TITLE_VIEW: 
      TitleHolder titleHolder = (TitleHolder) holder; 
      configureTitleHolder(titleHolder, position); 
      break; 
     case INPUT: 
      InputHolder inputHolder = (InputHolder) holder; 
      configureInputHolder(inputHolder, position); 
      break; 
    } 
} 

private void configureCheckBoxHolder(CheckboxHolder holder,int position) { 
    CheckBoxElement boxElement = (CheckBoxElement) items.get(position); 
    if (boxElement != null) { 
     holder.box.setText(boxElement.getText()); 
    } 
} 

private void configureInputHolder(InputHolder holder,int position) { 
    InputField field = (InputField) items.get(position); 
    if (field != null) { 
     holder.title.setText(field.getSubtitle()); 
    } 
} 

private void configureTitleHolder(TitleHolder holder,int position) { 
    TitlePojo titlePojo = (TitlePojo) items.get(position); 
    if (titlePojo != null) { 
     holder.titleText.setText(titlePojo.getTitle()); 
    } 
} 

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

private class InputHolder extends RecyclerView.ViewHolder { 
    private TextView title; 
    private EditText inputfield; 

    public InputHolder(View v1) { 
     super(v1); 
     title = (TextView) v1.findViewById(R.id.inputTitleItem); 
     inputfield = (EditText) v1.findViewById(R.id.fieldItem); 
    } 
} 

private class TitleHolder extends RecyclerView.ViewHolder { 
    private TextView titleText; 

    public TitleHolder(View v1) { 
     super(v1); 
     titleText = (TextView) v1.findViewById(R.id.titleView); 
    } 
} 

private class CheckboxHolder extends RecyclerView.ViewHolder { 
    private CheckBox box; 

    public CheckboxHolder(View v1) { 
     super(v1); 
     box = (CheckBox) v1.findViewById(R.id.checkboxItem); 
    } 
} 

private class RadioGroupHolder extends RecyclerView.ViewHolder { 
    private RadioGroup group; 

    public RadioGroupHolder(View v1) { 
     super(v1); 

    } 
} 

}

+0

Was sind element1, element2, 3 hier? – ChaitanyaAtkuri

+0

die Zeilen in der RecyclerView. Ich werde das ändern – Pynnie

+0

Wie wäre es, wenn Sie nur eine Ansicht mit allen Textansichten, Kontrollkästchen und Optionsfeldern erstellen, die Sie brauchen, und setzen Sie ihre Sichtbarkeit auf gegangen. Sie können ihre Sichtbarkeit in Ihrem Halter sichtbar ändern, wenn sie benötigt werden. – paul590

Antwort

1

@Pynnie, Dies ist keine große Sache. Ich glaube, du wirst es lösen. Lemme gebe dir etwas Licht, um das zu lösen.

Schritt1: Da wir wie erwähnt drei verschiedene Arten von Ansichten haben, nehmen wir eine List<Object> dataList= new ArrayList(); Diese Liste wird entscheiden, die Gesamtzahl der Ansichten angezeigt werden soll.

Schritt 2: Jetzt machen wir einen ViewType für jede der verfügbaren Komponenten. Zum Beispiel:

Speichern Sie nun die Daten dynamisch auf der Grundlage der Struktur und speichern Sie sie auf folgende Weise.

public class TextViewPojo { // This will used for identifying textViews 

public String text; 
//Any other necessary variables to hold data to display 
} 

public class EditTextPojo { // This will used for identifying editText 

public String text; 
//Any other necessary variables to hold data to display 
} 

public class RadioGroupPojo { // This will used for identifying RadioGroup 

public int noOfRadioButtons; 
//Any other necessary variables to hold data to display 
} 

public class CheckBoxPojo { // This will used for identifying checkbox 

public String text; 
//Any other necessary variables to hold data to display 
} 

// ------------------ row1 - Textview anzeigt Subtitle ->dataList.add(new TextViewPojo()); 1) Auswahl1 - EditText ->dataList.add(new EditTextPojo()); 2) choice2- EditText ->dataList.add(new EditTextPojo()); // ------------------ row2- Textview anzeigt Untertitel ->dataList.add(new TextViewPojo()); 1) Auswahl1 -Checkbox ->dataList.add(new CheckBoxPojo()); 2) choice2-CheckBox - >dataList.add(new CheckBoxPojo()); 3) choice3-CheckBox ->dataList.add(new CheckBoxPojo()); // --------------- --- row3 - Textview anzeigt UNTERTITEL ->dataList.add(new TextViewPojo()); 1) Choice1 - Radiogroup Für beide Choice1, choice2 als einer, wie es eine Gruppe von Optionsfeldern zu betrachten, ->RadioGroup -> dataList.add(new RadioGroupPojo()); 2) Choice2 // ------ -------------

nun zur Umsetzung RecyclerView Adapter kommenden

public class RecyclerViewsAdapter RecyclerView.Adapter erstreckt {

// The items to display in your RecyclerView 
private List<Object> items; 
private final int TEXT_VIEW = 0; //For TextView 
private final int RADIO_GROUP = 1; //For RadioGroup 
private final int CHECK_BOX = 2; //For individual Checkbox 
private final int EDIT_TEXT = 3; //For Edit text individual 

public RecyclerViewsAdapter(List<Object> data,) { 
this.items = data; 
} 

und nun die Daten zu unterscheiden, wir werden das getV benutzen iewType() Methode

// Gibt den Ansichtstyp des Artikels an der Position für die Zwecke der Ansichtsrecycling zurück.

@Override 
    public int getItemViewType(int position) { 
     if (items.get(position) instanceof CheckBoxPojo) { 
      return CHECK_BOX; 
     } else if (items.get(position) instanceof RadioGroupPojo) { 
      return RADIOGROUP; 
     } //All the conditions follow.. 
     return -1; 
    } 

Erstellen Sie nun Viewholders für jeden der Typen.

public class ViewHolder1 extends RecyclerView.ViewHolder { 

    private TextView label1; 

    public ViewHolder1(View v) { 
     super(v); 
     label1 = (TextView) v.findViewById(R.id.text1); 
    } 

    public TextView getLabel1() { 
     return label1; 
    } 

    public void setLabel1(TextView label1) { 
     this.label1 = label1; 
    } 
} 

// die anderen viewHolders entsprechend All.

@Override 
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { 

     RecyclerView.ViewHolder viewHolder; 
     LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext()); 

     switch (viewType) { 
      case CHECKBOX: 
       View v1 = inflater.inflate(R.layout.layout_viewholder1, viewGroup, false); 
       viewHolder = new ViewHolder1(v1); 
       break; 
      case RADIOGROUP: 
       View v2 = inflater.inflate(R.layout.layout_viewholder2, viewGroup, false); 
       viewHolder = new ViewHolder2(v2); 
       break; 

// Und die restlichen Fälle folgen.

NeXT Datensatz zu Ansichten

@Override 
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) { 
     switch (viewHolder.getItemViewType()) { 
      case CHECKBOX: 
       ViewHolder1 vh1 = (ViewHolder1) viewHolder; 
       configureViewHolder1(vh1, position); 
       break; 
      case RADIOGROUp: 
       ViewHolder2 vh2 = (ViewHolder2) viewHolder; 
       configureViewHolder2(vh2, position); 
       break; 
//Rest cases follow. 
      default: 
       RecyclerViewSimpleTextViewHolder vh = (RecyclerViewSimpleTextViewHolder) viewHolder; 
       configureDefaultViewHolder(vh, position); 
       break; 
     } 
    } 

private void configureViewHolder1(ViewHolder1 vh1, int position) { 
     CheckBoxPojo user = (CheckBoxPojo) items.get(position); 
     if (user != null) { 
      vh1.getCheckBox1().setChecked(user.isChecked); 
     } 
    } 

    private void configureViewHolder2(ViewHolder2 vh2) { 
     //vh2.getImageView().setImageResource(R.drawable.sample_golden_gate); 
Similarly rest follows. 
    } 

Und das ist es geschafft !!! Sie können konfigurieren, auf welche Weise, wie viele es jemals sein mögen, wie zufällig sie sogar sein mögen.

REFERENZ: https://guides.codepath.com/android/Heterogenous-Layouts-inside-RecyclerView

EDIT:

Um das Problem im Snippet hinzugefügt von Ihnen zu erfahren. Unten ist die Frage:

case TITLE_VIEW: View v2 = inflater.inflate(R.layout.child_title, parent, false); viewHolder = new TitleHolder(v2); break; case INPUT: View v3 = inflater.inflate(R.layout.child_inputfield, parent, false); viewHolder = new TitleHolder(v3); break;

beide in diesen Fällen nur Titelhalter verwenden.

+0

danke für die Hilfe, das scheint der richtige Ansatz zu sein! Sehr schöne Erklärung! Aber ich habe immer noch ein Problem in 'onBindViewholder()'. Es ist wirklich veraltet, weil das erste Element (TitlePojo) kein Problem ist, aber das nächste Element ein editTextPojo ist, das eine classCastException auslöst. Es springt in den richtigen Fall, wo es in einen ViewHolder für EditText umgewandelt werden sollte, aber irgendwie ist der übergebene ViewHolder immer noch ein TitleHolder, der nicht in einen EditTextHolder umgewandelt werden kann ... Ich verstehe nicht, was los ist – Pynnie

+1

@Pynnie, füge das Code-Snippet ein wo Sie mit diesem Problem konfrontiert sind und genaues Problem ur bekommen – ChaitanyaAtkuri

+0

Ich habe den Code der Frage unter EDIT :) – Pynnie

Verwandte Themen