Search code examples
androidlistviewandroid-linearlayout

How to inflate different layout in Listview row using Viewholder pattern


To learn Android programming I'm trying to code a small dictionary program. Currently I'm trying to list all entries but with no success :

One entry can have more than one definition :

Entry 1
Definition 1.1
Entry 2
Definition 2.1
Definition 2.2
Definition 2.3
Entry 3
Definition 3.1
Definition 3.2
Entry 4
Definition 4.1

But there's something not clear which I have to ask :

I have three xml files (all three are of type LinearLayout):

1) fragment_entries : it contains one ListView

    android:id="@+id/list_view_entries"

2) fragment_entries_row : it contains one TextView

    android:id="@+id/text_view_entries_word"

3) fragment_entries_definitions_row : it contains two TextViews

    android:id="@+id/definitions_row_word_type"
    android:id="@+id/definitions_row_meaning"

And one Adapter :

EntriesAdapter extends ArrayAdapter<EntryVO>

the getView method where things become messy :

@Override
public View getView(int position, View listViewEntriesRow, ViewGroup parent) {
    ViewHolder viewHolder = null;
    if (listViewEntriesRow == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        listViewEntriesRow = inflater.inflate(R.layout.fragment_entries_row, null);

        viewHolder = new ViewHolder();
        viewHolder.entriesWord = (TextView) listViewEntriesRow.findViewById(R.id.text_view_entries_word);
        viewHolder.entriesDefinitions = inflater.inflate(R.layout.fragment_entries_definitions_row, null);
        listViewEntriesRow.setTag(viewHolder);
    } else
        viewHolder = (ViewHolder) listViewEntriesRow.getTag();

    EntryVO entryVO = getItem(position);

    for (DefinitionVO definitionVO : entryVO.getDefinitions()) {
         here : inflate 3rd xml in every loop ?
        // definitionVO.getType()
        // definitionVO.getMeaning()
    }

    return listViewEntriesRow;
}

finally the ViewHolder class looks like this :

private static class ViewHolder {
    TextView entriesWord; // of 2nd xml file
    View     entriesDefinitions; // 3rd xml file
}

I'm stuck because I have to inflate the 3rd xml file content in a loop to append it to under the entry text view and that doesn't look right (performance wise at least).

Can you help me ?

Thanks in advance.


Solution

  • I solved this using a RecyclerView instead.

    <RelativeLayout>
        <android.support.v7.widget.RecyclerView>
    </RelativeLayout>
    

    Every entry is a cardview:

    <android.support.v7.widget.CardView>
    

    in EntriesAdapter :

    @Override
        public void onBindViewHolder(EntryViewHolder vh, int position) {
            final EntryVO entryVO = entries.get(position);
            vh.cv.removeAllViewsInLayout();
            vh.cv.addView(EntriesAdapter.createEntryCardViewTable(context, entryVO, new ReadListener(context)));
        }
    

    Finally in createEntryCardViewTable method I construct a TableLayout programmatically like an HTML table with rows for the entry and its definitions.

    Performance is great, despite the 1000+ entries (every entry may have more than one definition).