2017-01-11 8 views
0

私は以下の状況に直面しています:私は3種類のビュータイプを持つRecyclerViewを持っています。それぞれにはサブタイトルが含まれ、次にラジオグループ、チェックボックス、またはeditTextが含まれます。問題は、要素の数(edittext、checkbox、radiobuttons)が可変であるため、ビュータイプとして静的テンプレートを作成できないことです。だから、私はこのようなものに到達しようとしています(ラジオボタンの例):RecyclerView - 要素数が不明なリストアイテム

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

良いアプローチについてのアイデアはありますか?あなたに時間と助けをありがとう! :)

EDIT:ChaitanyaAtkurisの回答はかなり役に立ちましたが、onBindViewHolder()でClassCastExceptionが発生しました。それは、「InputHolderにTitleHolderをキャストできません」と言いますが、正しいケース(INPUT)を使用するため、ホルダーオブジェクトが実際にTitleHolderである理由を理解できません。ここに私のアダプタのコードが

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

あなたが必要とするすべてのtextviews、チェックボックス、ラジオボタンを備えた1つのビューを作成し、その可視性をなくす方法はありますか?必要に応じて、所有者の視認性を視覚的に変更することができます。 – paul590

答えて

1

@Pynnieあり、これは大したことではありません。私はあなたがそれを解決すると信じています。 Lemmeはこれを解決するための光を与えます。

ステップ1:前述のように3種類のビューがあるので、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示すサブタイトル - >dataList.add(new TextViewPojo()); 1)choice1 - のEditText - >dataList.add(new EditTextPojo()); 2)choice2- EditText - >dataList.add(new EditTextPojo()); // ------------------ row2-のTextView示すサブタイトル - >dataList.add(new TextViewPojo()); 1)choice1 -CheckBox - >dataList.add(new CheckBoxPojo()); 2)choice2、チェックボックス - >dataList.add(new CheckBoxPojo()); 3)choice3-CheckBox - >dataList.add(new CheckBoxPojo()); // --------------- --- ROW3 - のTextView示すサブタイトル - >dataList.add(new TextViewPojo()); 1)choice1 - 両方choice1についてRADIOGROUP、そのような一つのラジオボタンのグループとして考えるchoice2 - >RadioGroup -> dataList.add(new RadioGroupPojo()); 2)choice2 // ------ -------------

パブリッククラス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; 
} 

、現在を拡張RecyclerViewアダプタ実装に来私たちは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. 
    } 

そしてthatsはそれが行わビューにデータを設定!これまでに何があったのか、どのくらいランダムであっても構いません。

REFERENCE: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がclassCastExceptionをスローするため、本当にうまくいきます。それは正しいケースにジャンプし、EditTextのためにViewHolderにキャストする必要がありますが、何とか渡されたViewHolderはまだEditTextHolderにキャストできないTitleHolderです...何かが間違っています。 – Pynnie

+1

@Pynnie、コードスニペットを貼り付けますあなたはこの問題に直面していて、正確な問題は、 – ChaitanyaAtkuri

+0

私はEDITの下の質問にコードを追加して得ています。 – Pynnie

関連する問題