Setting up the adapter
ArrayList<MenuRow> menu = new ArrayList<MenuRow>();
menu.add(new MenuChild(MenuPosition.DASHBOARD, getString(R.string.dashboard)));
menu.add(new MenuChild(MenuPosition.HISTORY, getString(R.string.history)));
MenuGroup group= new MenuGroup(MenuPosition.MY_GROUP,
getString(R.string.my_group));
group.items.add(new MenuChild(MenuPosition.CHILD_ITEM,
getString(R.string.child_item)));
group.items.add(new MenuChild(MenuPosition.CHILD_ITEM_2,
getString(R.string.child_item2)));
menu.add(group);
menu.add(new MenuChild(MenuPosition.SETTINGS, getString(R.string.settings)));
adapter = new MenuAdapter(context, menu);
myExpandableListView.setAdapter(adapter);
The adapter
public class MenuAdapter extends BaseExpandableListAdapter {
private Context context;
private ArrayList<MenuRow> menu;
private int selectedGroupIndex = 0;
private int selectedChildIndex = 0;
public MenuAdapter(Context context, ArrayList<MenuRow> menu) {
this.context = context;
this.menu = menu;
}
public void setSelectedGroupIndex(int selectedGroupIndex) {
this.selectedGroupIndex = selectedGroupIndex;
notifyDataSetChanged();
}
public boolean isGroupSelected(int position) {
return position == selectedGroupIndex;
}
public int getSelectedGroupIndex() {
return selectedGroupIndex;
}
public void setSelectedChildIndex(int selectedChildIndex) {
this.selectedChildIndex = selectedChildIndex;
notifyDataSetChanged();
}
public boolean isChildSelected(int position) {
return position == selectedChildIndex;
}
public int getSelectedItemIndex() {
return selectedChildIndex;
}
@Override
public Object getChild(int groupPosition, int childPosition) {
MenuRow row = menu.get(groupPosition);
if (row.isShownAsGroup()) {
ArrayList<MenuChild> childs = ((MenuGroup) row).getItems();
return childs.get(childPosition);
} else {
return null;
}
}
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View view, ViewGroup parent) {
MenuChild child = (MenuChild) getChild(groupPosition, childPosition);
if (view == null) {
LayoutInflater infalInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = infalInflater.inflate(R.layout.menu_child_item, null);
}
TextView txtMenu = (TextView) view.findViewById(R.id.txt_menu);
txtMenu.setText(child.getTitle());
if (groupPosition == selectedGroupIndex
&& childPosition == selectedChildIndex) {
txtMenu.setTextColor(context.getResources().getColor(
R.color.turquoise));
} else {
txtMenu.setTextColor(context.getResources().getColor(
R.color.blue_grey));
}
return view;
}
public int getChildrenCount(int groupPosition) {
MenuRow row = menu.get(groupPosition);
if (row.isShownAsGroup()) {
return ((MenuGroup) row).items.size();
} else {
return 0;
}
}
public Object getGroup(int groupPosition) {
return menu.get(groupPosition);
}
public int getGroupCount() {
return menu.size();
}
public long getGroupId(int groupPosition) {
return groupPosition;
}
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
public View getGroupView(int groupPosition, boolean isLastChild, View view,
ViewGroup parent) {
MenuRow row = menu.get(groupPosition);
MenuPosition menuPosition = row.getMenuPosition();
if (view == null) {
LayoutInflater inf = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inf.inflate(R.layout.menu_group_item, null);
}
RelativeLayout rootLayout = (RelativeLayout) view
.findViewById(R.id.root_layout);
TextView txtMenuItem = (TextView) view.findViewById(R.id.txt_menu);
ImageView icon = (ImageView) view.findViewById(R.id.ic_menu);
ImageView dropDownMenuIndicator = (ImageView) view
.findViewById(R.id.ic_drop_down_arrow);
txtMenuItem.setText(row.getTitle());
if (row.isShownAsGroup()) {
dropDownMenuIndicator.setVisibility(View.VISIBLE);
} else {
dropDownMenuIndicator.setVisibility(View.GONE);
}
StateListDrawable iconStates;
if (groupPosition == selectedGroupIndex) {
boolean isActive = true;
// Needed for correct images onPressedStates
txtMenuItem.setTextColor(getTextStates(isActive));
iconStates = getIconStates(menuPosition, isActive);
rootLayout.setBackgroundColor(context.getResources().getColor(
R.color.light_grey));
} else {
boolean isActive = false;
// Needed for correct images onPressedStates
txtMenuItem.setTextColor(getTextStates(isActive));
iconStates = getIconStates(menuPosition, isActive);
rootLayout.setBackgroundColor(context.getResources().getColor(
R.color.white));
}
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) {
icon.setBackgroundDrawable(iconStates);
} else {
icon.setBackground(iconStates);
}
return view;
}
public boolean hasStableIds() {
return true;
}
public boolean isChildSelectable(int arg0, int arg1) {
return true;
}
private ColorStateList getTextStates(boolean isActive) {
int ressourceId = 0;
if (isActive) {
ressourceId = R.color.selector_menu_item_txt_selected;
} else {
ressourceId = R.color.selector_menu_item_txt;
}
return context.getResources().getColorStateList(ressourceId);
}
private StateListDrawable getIconStates(MenuPosition menuPosition,
boolean isActive) {
StateListDrawable states = new StateListDrawable();
switch (menuPosition) {
case DASHBOARD:
states.addState(
new int[] { android.R.attr.state_pressed },
context.getResources().getDrawable(
R.drawable.ic_menu_dashboard_active));
if (isActive) {
states.addState(new int[] {}, context.getResources()
.getDrawable(R.drawable.ic_menu_dashboard_active));
} else {
states.addState(new int[] {}, context.getResources()
.getDrawable(R.drawable.ic_menu_dashboard));
}
break;
case HISTORY:
states.addState(
new int[] { android.R.attr.state_pressed },
context.getResources().getDrawable(
R.drawable.ic_menu_history_active));
if (isActive) {
states.addState(new int[] {}, context.getResources()
.getDrawable(R.drawable.ic_menu_history_active));
} else {
states.addState(new int[] {}, context.getResources()
.getDrawable(R.drawable.ic_menu_history));
}
break;
case SETTINGS:
states.addState(
new int[] { android.R.attr.state_pressed },
context.getResources().getDrawable(
R.drawable.ic_menu_settings_active));
if (isActive) {
states.addState(new int[] {}, context.getResources()
.getDrawable(R.drawable.ic_menu_settings_active));
} else {
states.addState(new int[] {}, context.getResources()
.getDrawable(R.drawable.ic_menu_settings));
}
break;
default:
break;
}
return states;
}
}
MenuPosition Enum
public enum MenuPosition {
DASHBOARD(0, -1), HISTORY(1, -1), SETTINGS(2, -1);
private final int childPosition;
private final int groupPosition;
MenuPosition(int groupPosition, int childPosition) {
this.groupPosition = groupPosition;
this.childPosition = childPosition;
}
public int getGroupIndex() {
return groupPosition;
}
public int getChildIndex() {
return childPosition;
}
}
The getIconStates
and getTextStates
are for if you want to add other states than just selected/unselected, in my case I wanted to add state_pressed
I tried using a ColorStateList but with no avail so I used this workaround
selector_menu_item_txt
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="@color/turquoise"/>
<item android:color="@color/blue_grey"/>
</selector>
selector_menu_item_txt_selected
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/turquoise"/>
</selector>