i have codes from this project, and i want to implement expandable third level child OnItemClick, i tried to use concept from this 2 level expandablelistview child click listener but it did not work. SO how can i make user know has selected certain parent/group level, second level and third level items.
here is my codes:
MainPageActivity.java
public class MainPageActivity extends AppCompatActivity {
private ExpandableListView expandableListView;
String[] parent = new String[]{"group 1", "group 2"};
String[] q1 = new String[]{"Child Level 1", "Child level 2"};
String[] q2 = new String[]{"Child Level 1B", "Child Level 2B"};
String[] q3 = new String[]{"Child Level 1C"};
String[] des1 = new String[]{"A","B","C"};
String[] des2 = new String[]{"D","E","F"};
String[] des3 = new String[]{"G"};
String[] des4 = new String[]{"H","J"};
String[] des5 = new String[]{"U."," R"," V"};
LinkedHashMap<String, String[]> thirdLevelq1 = new LinkedHashMap<>();
LinkedHashMap<String, String[]> thirdLevelq2 = new LinkedHashMap<>();
LinkedHashMap<String, String[]> thirdLevelq3 = new LinkedHashMap<>();
/**
* Second level array list
*/
List<String[]> secondLevel = new ArrayList<>();
/**
* Inner level data
*/
List<LinkedHashMap<String, String[]>> data = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_page);
setUpAdapter();
}
private void setUpAdapter() {
secondLevel.add(q1);
secondLevel.add(q2);
secondLevel.add(q3);
thirdLevelq1.put(q1[0], des1);
thirdLevelq1.put(q1[1], des2);
thirdLevelq2.put(q2[0], des3);
thirdLevelq2.put(q2[1], des4);
thirdLevelq3.put(q3[0], des5);
data.add(thirdLevelq1);
data.add(thirdLevelq2);
data.add(thirdLevelq3);
expandableListView = (ExpandableListView) findViewById(R.id.expandible_listview);
//passing three level of information to constructor
ThreeLevelListAdapter threeLevelListAdapterAdapter = new ThreeLevelListAdapter(this, parent, secondLevel, data);
expandableListView.setAdapter(threeLevelListAdapterAdapter);
expandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
int previousGroup = -1;
@Override
public void onGroupExpand(int groupPosition) {
if (groupPosition != previousGroup)
expandableListView.collapseGroup(previousGroup);
previousGroup = groupPosition;
}
});
// ExpandableListView on child click listener
expandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
String[] value= secondLevel.get(groupPosition);
Toast.makeText(
getApplicationContext(),
secondLevel.get(groupPosition)
+ " : ", Toast.LENGTH_SHORT)
.show();
return false;
}
}); }}
SecondLevelExpandableListView.java
public class SecondLevelExpandableListView extends ExpandableListView {
public SecondLevelExpandableListView(Context context) {
super(context);
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(999999, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
SecondLevelAdapter.java
public class SecondLevelAdapter extends BaseExpandableListAdapter {
private Context context;
List<String[]> data;
String[] headers;
ImageView ivGroupIndicator;
public SecondLevelAdapter(Context context, String[] headers, List<String[]> data) {
this.context = context;
this.data = data;
this.headers = headers;
}
@Override
public Object getGroup(int groupPosition) {
return headers[groupPosition];
}
@Override
public int getGroupCount() {
return headers.length;
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.row_second, null);
TextView text = (TextView) convertView.findViewById(R.id.rowSecondText);
String groupText = getGroup(groupPosition).toString();
text.setText(groupText);
return convertView;
}
@Override
public Object getChild(int groupPosition, int childPosition) {
String[] childData;
childData = data.get(groupPosition);
return childData[childPosition];
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.row_third, null);
TextView textView = (TextView) convertView.findViewById(R.id.rowThirdText);
String[] childArray = data.get(groupPosition);
String text = childArray[childPosition];
textView.setText(text);
return convertView;
}
@Override
public int getChildrenCount(int groupPosition) {
String[] children = data.get(groupPosition);
return children.length;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
ThreeLevelListAdapter .java
public class ThreeLevelListAdapter extends BaseExpandableListAdapter {
String[] parentHeaders;
List<String[]> secondLevel;
private Context context;
List<LinkedHashMap<String, String[]>> data;
/**
* Constructor
* @param context
* @param parentHeader
* @param secondLevel
* @param data
*/
public ThreeLevelListAdapter(Context context, String[] parentHeader, List<String[]> secondLevel, List<LinkedHashMap<String, String[]>> data) {
this.context = context;
this.parentHeaders = parentHeader;
this.secondLevel = secondLevel;
this.data = data;
}
@Override
public int getGroupCount() {
return parentHeaders.length;
}
@Override
public int getChildrenCount(int groupPosition) {
// no idea why this code is working
return 1;
}
@Override
public Object getGroup(int groupPosition) {
return groupPosition;
}
@Override
public Object getChild(int group, int child) {
return child;
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.row_first, null);
TextView text = (TextView) convertView.findViewById(R.id.rowParentText);
text.setText(this.parentHeaders[groupPosition]);
return convertView;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
final SecondLevelExpandableListView secondLevelELV = new SecondLevelExpandableListView(context);
String[] headers = secondLevel.get(groupPosition);
List<String[]> childData = new ArrayList<>();
HashMap<String, String[]> secondLevelData = data.get(groupPosition);
for (String key : secondLevelData.keySet()) {
childData.add(secondLevelData.get(key));
}
secondLevelELV.setAdapter(new SecondLevelAdapter(context, headers, childData));
secondLevelELV.setGroupIndicator(null);
secondLevelELV.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
int previousGroup = -1;
@Override
public void onGroupExpand(int groupPosition) {
if (groupPosition != previousGroup)
secondLevelELV.collapseGroup(previousGroup);
previousGroup = groupPosition;
}
});
return secondLevelELV;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
}
You can get the item clicked at the third level by creating interface in the ThreeLevelListAdapter and implemented in the activity. Try below:
MainPageActivity.java:
public class MainPageActivity extends AppCompatActivity implements ThreeLevelListAdapter.ThreeLevelListViewListener{
private ExpandableListView expandableListView;
String[] parent = new String[]{"group 1", "group 2"};
String[] q1 = new String[]{"Child Level 1", "Child level 2"};
String[] q2 = new String[]{"Child Level 1B", "Child Level 2B"};
String[] q3 = new String[]{"Child Level 1C"};
String[] des1 = new String[]{"A","B","C"};
String[] des2 = new String[]{"D","E","F"};
String[] des3 = new String[]{"G"};
String[] des4 = new String[]{"H","J"};
String[] des5 = new String[]{"U."," R"," V"};
LinkedHashMap<String, String[]> thirdLevelq1 = new LinkedHashMap<>();
LinkedHashMap<String, String[]> thirdLevelq2 = new LinkedHashMap<>();
LinkedHashMap<String, String[]> thirdLevelq3 = new LinkedHashMap<>();
/**
* Second level array list
*/
List<String[]> secondLevel = new ArrayList<>();
/**
* Inner level data
*/
List<LinkedHashMap<String, String[]>> data = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_page);
setUpAdapter();
}
private void setUpAdapter() {
secondLevel.add(q1);
secondLevel.add(q2);
secondLevel.add(q3);
thirdLevelq1.put(q1[0], des1);
thirdLevelq1.put(q1[1], des2);
thirdLevelq2.put(q2[0], des3);
thirdLevelq2.put(q2[1], des4);
thirdLevelq3.put(q3[0], des5);
data.add(thirdLevelq1);
data.add(thirdLevelq2);
data.add(thirdLevelq3);
expandableListView = (ExpandableListView) findViewById(R.id.expandable_listview);
//passing three level of information to constructor
ThreeLevelListAdapter threeLevelListAdapterAdapter = new ThreeLevelListAdapter(this, parent, secondLevel, data, this);
expandableListView.setAdapter(threeLevelListAdapterAdapter);
expandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
int previousGroup = -1;
@Override
public void onGroupExpand(int groupPosition) {
if (groupPosition != previousGroup)
expandableListView.collapseGroup(previousGroup);
previousGroup = groupPosition;
}
});
}
@Override
public void onFinalChildClick(int plpos, int slpos, int tlpos) {
Toast.makeText(this, plpos + ", " + slpos + ", " + tlpos, Toast.LENGTH_SHORT).show();
}
@Override
public void onFinalItemClick(String plItem, String slItem, String tlItem) {
Toast.makeText(this, plItem + ", " + slItem + ", " + tlItem, Toast.LENGTH_SHORT).show();
}
}
ThreeLevelListAdapter .java:
public class ThreeLevelListAdapter extends BaseExpandableListAdapter {
String[] parentHeaders;
List<String[]> secondLevel;
private Context context;
List<LinkedHashMap<String, String[]>> data;
ThreeLevelListViewListener mThreeLevelListViewListener;
/**
* Constructor
* @param context
* @param parentHeader
* @param secondLevel
* @param data
* @param listener
*/
public ThreeLevelListAdapter(Context context, String[] parentHeader, List<String[]> secondLevel,
List<LinkedHashMap<String, String[]>> data,
ThreeLevelListViewListener listener) {
this.context = context;
this.parentHeaders = parentHeader;
this.secondLevel = secondLevel;
this.data = data;
mThreeLevelListViewListener = listener;
}
@Override
public int getGroupCount() {
return parentHeaders.length;
}
@Override
public int getChildrenCount(int groupPosition) {
// no idea why this code is working
return 1;
}
@Override
public Object getGroup(int groupPosition) {
return parentHeaders[groupPosition];
}
@Override
public Object getChild(int group, int child) {
return child;
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.row_first, null);
TextView text = (TextView) convertView.findViewById(R.id.rowParentText);
text.setText(this.parentHeaders[groupPosition]);
return convertView;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
final SecondLevelExpandableListView secondLevelELV = new SecondLevelExpandableListView(context);
String[] headers = secondLevel.get(groupPosition);
List<String[]> childData = new ArrayList<>();
HashMap<String, String[]> secondLevelData = data.get(groupPosition);
for (String key : secondLevelData.keySet()) {
childData.add(secondLevelData.get(key));
}
secondLevelELV.setAdapter(new SecondLevelAdapter(context, headers, childData));
secondLevelELV.setGroupIndicator(null);
secondLevelELV.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
int previousGroup = -1;
@Override
public void onGroupExpand(int groupPosition) {
if (groupPosition != previousGroup)
secondLevelELV.collapseGroup(previousGroup);
previousGroup = groupPosition;
}
});
secondLevelELV.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView expandableListView, View view, int i, int i1, long l) {
int ppos = (int)expandableListView.getTag();
mThreeLevelListViewListener.onFinalChildClick(ppos, i, i1);
String plItem = (String)getGroup(ppos);
SecondLevelAdapter adapter = (SecondLevelAdapter)expandableListView.getExpandableListAdapter();
String slItem = (String)adapter.getGroup(i);
String tlItem = (String)adapter.getChild(i, i1);
mThreeLevelListViewListener.onFinalItemClick(plItem, slItem, tlItem);
return true;
}
});
secondLevelELV.setTag(groupPosition);
return secondLevelELV;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
public interface ThreeLevelListViewListener{
void onFinalChildClick(int plpos, int slpos, int tlpos);
void onFinalItemClick(String plItem, String slItem, String tlItem);
}
}
Hope that helps!