0

I have a list view that displays two different kinds of data one is a separator. Each data type is stored in one array list. Thus there are two lists. The content of each list is separated from the other one by a special row (separator). The first row is a separator row as well. In getView i have to distinguish between normal data rows and separator rows.

// returns true if a separator row must be displayed at pos. 
private boolean isSeperator(int pos) {
        return pos == 0 || pos == data.size() + 1;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    LayoutInflater infalInflater = (LayoutInflater) this.context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    if(isSeperator(position)) {
        convertView = infalInflater.inflate(R.layout.list_view_seperator, parent, false);
        TextView seperator = (TextView) convertView.findViewById(R.id.tv_list_view_seperator);
        seperator.setText("Seperator");
    }
    else {
        convertView = infalInflater.inflate(R.layout.my_layout, parent, false);

        TextView txtview = (TextView) convertView.findViewById(R.id.foo);
        ImageView icon = (ImageView) convertView.findViewById(R.id.bar);

        MyData myData = (MyData) getItem(position);
        txtview.setText(myData.getName());
        icon.setImageBitmap(myData.getIcon());
    }

    return convertView;
}

First I check whether a separator has to be displayed on the current position. This works fine.

I tried to implement the view holder pattern, but I constantly fail. Can somebody could please show me how to use this pattern in such a case where different types of rows including separators must be taken into consideration?

Blundell
  • 75,855
  • 30
  • 208
  • 233
null
  • 1,369
  • 2
  • 18
  • 38
  • Here's an example from Google ; https://github.com/google/iosched/blob/master/android/src/main/java/com/google/samples/apps/iosched/ui/SimpleSectionedListAdapter.java – harism Oct 08 '14 at 09:04

2 Answers2

3

If you want to implement separators, I would strongly recommend that you do it using the viewType mechanism in the Adapter. So, if you have your adapter which already serves one type of View, you can override:

private final static int TYPE_SEPARATOR = 0;
private final static int TYPE_ITEM = 1;


@Override
public int getViewTypeCount() {
    return 2;
}

@Override
public int getItemViewType(int position) {
    return isSeparator(position) ? TYPE_SEPARATOR : TYPE_ITEM;
}

This way, when your getView() gets called, you will have the correct type of convertView (which can still also be null) and you should be fine with something like:

private final LayoutInflater mInflater;

public MyAdapter(Context context) {
    mInflater = LayoutInflater.from(context);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if (isSeparator(position)) {
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.list_separator, parent, false);
        }

        setupSeparator(convertView);
    } else {
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.list_item, parent, false);
        }

        setupListItem(convertView, position);
    }

    return convertView;
}

private boolean isSeparator(int position) {
    return position == 0 || position == data.size() + 1;    // Is the + 1 needed here?
}
rock3r
  • 701
  • 4
  • 14
1

Given your condition to determine whether a row is a separator (first or last), it seems like it doesn't need to be part of this list.

Consider using ListView.addHeader(View view) and ListView.addFooter(View view) instead (these need to be set before you do ListView.setAdapter(ListAdapter listAdapter)) if you need the separators to scroll with the list.

ataulm
  • 15,195
  • 7
  • 50
  • 92
  • Hi, i know these methods and `ListView.addHeader(View view)` would indeed be a good solution. However, the second seperator is located _between_ the content of my two lists and not and must not be placed at the end of list view. Each separator is the title of the following rows. – null Oct 08 '14 at 08:48
  • You have two ListViews? What do you mean by "two lists"? – ataulm Oct 08 '14 at 09:11
  • @ataulm he means he mixes data from two sources into this one adapter as far as I can tell. – rock3r Oct 08 '14 at 09:22
  • exactly, i have data from two sources (two array lists). – null Oct 08 '14 at 10:04
  • consider creating an adapter which handles the merging of these two lists (and maybe relevant separators) into a single data source. Then you can combine with seb's answer with view types. – ataulm Oct 08 '14 at 10:43