2

I am developing an android application where i am using a RecyclerView to display a list of items.I am getting the list from server as json.So my problem is within this list i am getting another list as item.That is if my main arraylist contain title and materials, the material is another arraylist.So can you please suggest a solution to display a list within recyclerview.

The code below is my adapter

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

    private Context mContext;
    private ArrayList<Curriculum> mArrayListCurriculum;

    public CurriculumAdapter(Context mContext, ArrayList<Curriculum> mArrayListCurriculum) {
        this.mContext = mContext;
        this.mArrayListCurriculum = mArrayListCurriculum;
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_key_features, parent,false);
        return new KeyFeatureViewHolder(v);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

        if (holder instanceof KeyFeatureViewHolder) {
            ((KeyFeatureViewHolder) holder).mTextViewFeatureTitle.setText(mArrayListCurriculum.get(position).getTitle());
        }
    }

    @Override
    public int getItemCount() {
        return mArrayListCurriculum == null ? 0 : mArrayListCurriculum.size();
    }

    public static class KeyFeatureViewHolder extends RecyclerView.ViewHolder {

        public TextView mTextViewFeatureTitle;

        public KeyFeatureViewHolder(View itemView) {
            super(itemView);
            mTextViewFeatureTitle = (TextView) itemView.findViewById(R.id.txtFeature);
        }
    }
}

The code below is my fragment with dummy arraylist data

public class CourseCurriculumFragment extends Fragment {

    private FragmentInterface mFragmentInterface;
    private ArrayList<Curriculum> mArrayListCurriculum;
    private ArrayList<Material> mArrayListMaterial;
    private RecyclerView mRecyclerViewCurriculum;
    private LinearLayoutManager mLinearLayoutManager;
    private CurriculumAdapter mCurriculumAdapter;

    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_course_curriculum, container, false);
        return view;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        initView(view);
    }

    private void initView(View view) {
        mArrayListMaterial = new ArrayList<>();
        mArrayListCurriculum = new ArrayList<>();
        populateMaterials();
        populateKeyFeatures();

        mRecyclerViewCurriculum = (RecyclerView) view.findViewById(R.id.recyclerViewCurriculum);
        mCurriculumAdapter = new CurriculumAdapter(getActivity(), mArrayListCurriculum);
        mLinearLayoutManager = new LinearLayoutManager(getActivity());
        mRecyclerViewCurriculum.setLayoutManager(mLinearLayoutManager);
        mRecyclerViewCurriculum.setAdapter(mCurriculumAdapter);
        mRecyclerViewCurriculum.setItemAnimator(new DefaultItemAnimator());
    }

    private void populateMaterials() {
        mArrayListMaterial.add(new Material("12:00","pdf","","Sample Text","0"));
        mArrayListMaterial.add(new Material("12:00","pdf","","Sample Text","0"));
    }

    private void populateKeyFeatures() {
        mArrayListCurriculum.add(new Curriculum("UNIT 1",mArrayListMaterial));
        mArrayListCurriculum.add(new Curriculum("UNIT 2",mArrayListMaterial));
        mArrayListCurriculum.add(new Curriculum("UNIT 3",mArrayListMaterial));
    }
}
Reaz Murshed
  • 23,691
  • 13
  • 78
  • 98
Lincy Laiju
  • 195
  • 4
  • 18
  • Hi Guys, Thanks for the reply.But what i have done is I have used a nested recycler view concept to achieve this.That is i have used a recyclerview and inside the adapter of that recyclerview i have added another recyclewrview to display the Material Arraylist. – Lincy Laiju Aug 04 '16 at 10:19

3 Answers3

1

A bind method in a holder is a good way to pass data to it.

In your case this bind method should take in a Curriculum and a Material object as parameters.

Inside the onBindViewHolder method of the adapter, instead of reaching into the variables of the holder, you should call this bind method.

In the implementation of the method inside the you KeyFeatureViewHolder class you should use these passed parameters and display them in the appropriate UI elements.

Lastly, to get the Material object data into adapter, add ArrayList<Material> as a constructor parameter just like you did with Curriculum.

Mehmet K
  • 2,805
  • 1
  • 23
  • 35
1

Use RecyclerView with header, title as header and materials as items of that header. Look at this example.

Community
  • 1
  • 1
faranjit
  • 1,567
  • 1
  • 15
  • 22
1

You need to design a custom list for yourself. For example take an object like this.

public class ListItem {
    public curriculumName = null;
    public materialName = null;
}

Now populate this list after you parse the JSON string. Get your first Curriculum and populate the object like this

private ArrayList<ListItem> mListItemArray = new ArrayList<ListItem> ();

for(curriculum : mArrayListCurriculum) {

    ListItem mListItemHead = new ListItem();    
    mListItemHead.curriculumName = curriculum.getName();

    // Set the header here
    mListItemArray.add(mListItemHead);

    for(material : curriculum.getMaterials()){
        ListItem mListItem = new ListItem();
        mListItem.materialName = material.getName();

        // Add materials here
        mListItemArray.add(mListItem);
    }
}

Now, you've a list with headers and materials. When the materialName in your mListItemArray is null, it identifies that this is a header and vice versa.

Now the trick is to modify your adapter of your RecyclerView so that you can bind proper view to your items in your list.

You can find an indication from this answer on how you can achieve this desired behaviour.

Basically, the idea is to modify your getItemViewType to pass the proper view in your onBindViewHolder. Your getItemViewType might look like this.

@Override
public int getItemViewType(int position) {
    if (mListItemArray.get(position).curriculumName != null) {
        // This is where we'll add header.
        return HEADER_VIEW;
    }

    return super.getItemViewType(position);
}
Community
  • 1
  • 1
Reaz Murshed
  • 23,691
  • 13
  • 78
  • 98