1

I am creating a custom list view as explained in Android ListView headers.

This is my Item interface

public interface Item { public int getViewType(); public View getView(LayoutInflater inflater, View convertView); }

This is my Header class

public class Header implements Item {

    private final String name;

    public Header(String name) {
        this.name = name;
    }

    @Override
    public int getViewType() {
        return TwoTextArrayAdapter.rowType.HEADER_ITEM.ordinal();
    }

    @Override
    public View getView(LayoutInflater inflater, View convertView) {
        View rootView;
        if (convertView == null) {
            rootView = (View) inflater.inflate(R.layout.nav_header, null);
        } else {
            rootView = convertView;
        }

        TextView text = (TextView) rootView.findViewById(R.id.separator);
        text.setText(name);

        rootView.setEnabled(false);

        return rootView;
    }

And this is my list class

public class ListItem implements Item {

    private final String item;

    public ListItem(String item) {
        this.item = item;
    }

    @Override
    public int getViewType() {
        return TwoTextArrayAdapter.rowType.LIST_ITEM.ordinal();
    }

    @Override
    public View getView(LayoutInflater inflater, View convertView) {
        View rootView;

        if (convertView == null) {
            rootView = (View) inflater.inflate(android.R.layout.simple_list_item_activated_1, null);
        } else {
            rootView = convertView;
        }

        TextView text = (TextView) rootView.findViewById(android.R.id.text1);
        text.setText(item);

        return rootView;
    }
}

Also I am using TwoTextArrayAdapter extended from ArrayAdapter

public class TwoTextArrayAdapter extends ArrayAdapter<Item> {

private LayoutInflater mInflater;

public enum rowType {
    LIST_ITEM, HEADER_ITEM
}

public TwoTextArrayAdapter(Context context, List<Item> items) {
    super(context, 0, items);
    mInflater = LayoutInflater.from(context);
}

@Override
public int getViewTypeCount() {
    return rowType.values().length;
}

@Override
public int getItemViewType(int position) {
    return getItem(position).getViewType();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    return getItem(position).getView(mInflater, convertView);
}

}

This is how I use it

mDrawerListView = (ListView) inflater.inflate(R.layout.fragment_navigation_list, container, false);
        mDrawerListView.setFitsSystemWindows(true);

        mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                selectItem(position);
            }
        });

        List<Item> services = new ArrayList<Item>();
        services.add(new Header("Call Management"));
        services.add(new ListItem("Service 01"));
        services.add(new ListItem("Service 02"));

        TwoTextArrayAdapter adapter = new TwoTextArrayAdapter(getActivity(), services);
        mDrawerListView.setAdapter(adapter);

And my problem is when I set the onClickListener() for that ListView, all the items, including the Header items are treated as clickable items. I need to make sure that Android ignores Header items and allows user to click only the items in ListItem.

How can I do it?

Thank you

Community
  • 1
  • 1
Sudara
  • 4,769
  • 3
  • 34
  • 39

3 Answers3

2

override isEnabled inside TwoTextArrayAdapter. For instance

@Override
public boolean isEnabled(int position) {
    return getItem(position).getViewType() != HeaderType ;
}

here the documnetation

Blackbelt
  • 156,034
  • 29
  • 297
  • 305
  • **isEnabled**: *Returns true if the item at the specified position is not a separator.* - This will erroneously return ***`true`*** for separator's, since a `separator` *is-not-a* `HeaderType`. – samus Mar 06 '18 at 18:24
1

Better yet, when you add the header to the listview, add it like this:

listView.addHeaderView(view,null,false);
TheYargonaut
  • 195
  • 1
  • 13
  • This works for me... I checked for adapter override first b/c that's how I got an `ExpandableListAdapter` to do this (*isChildSelectable(int groupPos, int childPos)*). – samus Mar 06 '18 at 18:32
0

A modification to Blackbelt's answer

isEnabled

boolean isEnabled (int position)

Returns true if the item at the specified position is not a separator. (A separator is a non-selectable, non-clickable item). The result is unspecified if position is invalid. An ArrayIndexOutOfBoundsException should be thrown in that case for fast failure.

override isEnabled inside TwoTextArrayAdapter. For instance

@Override
public boolean isEnabled(int position) {
    if (getItem(position).getViewType() == HeaderType)
        return false;
    return super.isEnabled(position);
}
samus
  • 6,102
  • 6
  • 31
  • 69