2017-01-11 2 views
0

Я столкнулся со следующей ситуацией: у меня есть RecyclerView с 3 различными видами. Каждый из них содержит субтитры, а затем либо группу радиостанций, либо флажки, либо editText. Проблема в том, что количество элементов (edittext, checkbox, radiobuttons) является переменной, поэтому я не могу создать статический шаблон в качестве видов. Поэтому я пытаюсь достичь чего-то вроде этого (пример с радиообменами):RecyclerView - listitem с неизвестным количеством элементов

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

Любые идеи относительно хорошего подхода? Спасибо за ваше время и помощь! :)

EDIT: Ответ ChaitanyaAtkuris был весьма полезен, но я получаю исключение ClassCastException в onBindViewHolder(). В нем говорится, что «can not cast TitleHolder для InputHolder» ... но я не могу понять, почему объект-держатель фактически является TitleHolder, потому что он использует правильный случай (INPUT). Вот мой адаптер код

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

Что такое element1, element2, 3 здесь? – ChaitanyaAtkuri

+0

строки в recyclerView. Я изменю это – Pynnie

+0

Как насчет того, что вы создаете только один вид со всеми текстовыми полями, флажками и переключателями, которые вам нужны, и установите их видимость. Вы можете изменить их видимость на видимые в вашем держателе, если они понадобятся. – paul590

ответ

1

@Pynnie, это не имеет большого значения. Я верю, что вы разрешите это. Лемм даст вам немного света, чтобы решить эту проблему.

Шаг 1: Поскольку у нас есть три разных вида взглядов, как упомянуто, давайте возьмем List<Object> dataList= new ArrayList();. Этот список будет определять общее количество отображаемых представлений.

Шаг 2: Теперь давайте создадим viewType для каждого из доступных компонентов. Например,

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 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 с указанием SUBTITLE ->dataList.add(new TextViewPojo()); 1) Choice1 - EditText ->dataList.add(new EditTextPojo()); 2) choice2- EditText ->dataList.add(new EditTextPojo()); // ------------------ row2- TextView с указанием SUBTITLE ->dataList.add(new TextViewPojo()); 1) Choice1 -CheckBox ->dataList.add(new CheckBoxPojo()); 2) Choice2-CheckBox - >dataList.add(new CheckBoxPojo()); 3) выбор3-CheckBox ->dataList.add(new CheckBoxPojo()); // --------------- --- row3 - TextView с указанием Подзаголовок ->dataList.add(new TextViewPojo()); 1) Choice1 - RadioGroup Для обоих CHOICE1, Choice2 рассматривать как один, как это группа радиокнопок, ->RadioGroup -> dataList.add(new RadioGroupPojo()); 2) Choice2 // ------ -------------

Сейчас подходит к реализации RecyclerView адаптер

общественного класса RecyclerViewsAdapter расширяет RecyclerView.Adapter {

// 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; 
} 

и теперь, чтобы дифференцировать данные, мы будем использовать getV Метод iewType()

// Возвращает вид вида элемента в позиции для повторного использования вида.

@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; 
    } 

Теперь создайте держатели для каждого из типов.

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; 
    } 
} 

// Все остальные viewHolders соответственно.

@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; 

// И все остальные случаи следуют.

следующий набор данных для просмотров

@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. 
    } 

и то это сделали !!! Вы можете настроить каким бы то ни было способом, сколько бы это ни было, насколько они бывают случайными.

ССЫЛКА: https://guides.codepath.com/android/Heterogenous-Layouts-inside-RecyclerView

EDIT:

Чтобы выяснить вопрос в сниппет добавленной Вами. Ниже вопрос:

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;

В обоих этих случаях вы используете только правообладатель.

+0

спасибо за помощь, это, кажется, правильный подход! Очень приятное объяснение! Но у меня все еще есть проблема в onBindViewholder(). Это действительно связано с тем, что первый элемент (TitlePojo) не проблема, но следующий элемент - editTextPojo генерирует исключение классаCastException. Он перескакивает в правильное место, где его следует отбрасывать в ViewHolder für EditText, но каким-то образом прошедший ViewHolder по-прежнему является TitleHolder, который не может быть внесен в EditTextHolder ... Я не понимаю, что не так – Pynnie

+1

@Pynnie, вставьте фрагмент кода где вы столкнулись с этой проблемой и точным вопросом ур получения – ChaitanyaAtkuri

+0

Я добавил код на вопрос в EDIT :) – Pynnie

Смежные вопросы