Note: the response below is for a non-expandable list.
That is definitely doable. You can create rows not only for the options and headers, but also for the separators, and give these separator rows the style you want (height 0.5dp, desired margin).
Basically, the same solution as suggested in https://stackoverflow.com/a/13634801/1816603, but using 4 layouts: 2 for options (for parents and childs) and 2 for separators (parent-level separator and child-level separator).
For simplicity, the item type and content can be put together in the same string, or for a more elegant solution you could create a class containing the row type and row text.
final ListView drawerList = (ListView) findViewById(R.id.left_drawer);
// Add options to the list drawer
final List<String> listOptions = new ArrayList<>();
listOptions.add("1Parent 1");
listOptions.add("2Child 1");
listOptions.add("4");
listOptions.add("2Child 2");
listOptions.add("3");
listOptions.add("1Parent 2");
listOptions.add("3");
listOptions.add("1Parent 3");
drawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.list_item_parent, listOptions) {
@Override
public boolean areAllItemsEnabled()
{
return false;
}
@Override
public boolean isEnabled(int position)
{
String selected = listOptions.get(position);
if ( (selected.charAt(0) == '3') || (selected.charAt(0) == '4') )
return false;
else return true;
}
@Override
public View getView(int position, View coverView, ViewGroup vg) {
LayoutInflater inflater = (LayoutInflater) parent.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
int type = getItemViewType(position);
if (type == 1) // parent
{
View rowView = inflater.inflate(R.layout.list_item_parent, vg, false);
TextView text1 = (TextView) rowView.findViewById(R.id.list_item_text);
text1.setText(listOptions.get(position).substring(1));
return rowView;
}
else if (type == 2) // child
{
View rowView = inflater.inflate(R.layout.list_item_child, vg, false);
TextView text1 = (TextView) rowView.findViewById(R.id.list_item_text);
text1.setText(listOptions.get(position).substring(1));
return rowView;
}
else if (type == 3) // parent separator
{
View rowView = inflater.inflate(R.layout.list_separator_parent, vg, false);
return rowView;
}
else if (type == 4) // child separator
{
View rowView = inflater.inflate(R.layout.list_separator_child, vg, false);
return rowView;
}
}
@Override
public int getViewTypeCount() {
return 4;
}
@Override
public int getItemViewType(int position) {
String selected = listOptions.get(position);
return Character.getNumericValue(selected.charAt(0)) - 1;
}
});
Where the layouts would be defined as:
list_item_parent - Row with full width, for the text of the parent options
list_item_child - Row with margin on the left, for the text of the parent options
list_separator_parent - Row with dark background, height 0.5dp and full width
list_separator_child - Row with dark background, height 0.5dp and margin on the left