Try below sample:-
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<ExpandableListView
android:id="@+id/elvMain"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ExpandableListView>
</LinearLayout>
MainActivity.java:
public class MainActivity extends AppCompatActivity {
ArrayList<String> mainGroupList;
HashMap<String, ArrayList<String>> mainChildList;
CustomAdapter mainAdapter;
ExpandableListView elvMain;
int newDataSet = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
elvMain = findViewById(R.id.elvMain);
mainGroupList = new ArrayList<>();
mainChildList = new HashMap<>();
for(int i = 0; i < 20; i++){
ArrayList<String> tmpList = new ArrayList<>();
for(int j = 0; j< 17; j++){
tmpList.add("Child " + j);
}
mainChildList.put("Group " + i, tmpList);
mainGroupList.add("Group " + i);
}
mainAdapter = new CustomAdapter(this, mainGroupList, mainChildList);
elvMain.setAdapter(mainAdapter);
elvMain.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView absListView, int i) {}
@Override
public void onScroll(AbsListView absListView, int i, int i1, int i2) {
if(i2 == i + i1){
View lastView = absListView.getChildAt(i1 - 1);
if(lastView.getBottom() == absListView.getBottom()){
try{
String viewTag = lastView.getTag().toString();
if(viewTag.equals("Group")){
Toast.makeText(getApplicationContext(),
"No more data, unless expanded the last group!!",
Toast.LENGTH_SHORT).show();
//elvMain.expandGroup(mainAdapter.getGroupCount() - 1);
}
}catch(Exception e){
addNewData();
}
}
}
}
});
}
private void addNewData(){
newDataSet++;
for(int i = 0; i < 5; i++){
ArrayList<String> tmpList = new ArrayList<>();
for(int j = 0; j< 7; j++){
tmpList.add("Child " + j);
}
mainChildList.put("Added " + newDataSet + ",Group " + i, tmpList);
mainGroupList.add("Added " + newDataSet + ",Group " + i);
}
mainAdapter.notifyDataSetChanged();
}
}
CustomAdapter.java:
public class CustomAdapter extends BaseExpandableListAdapter {
ArrayList<String> groupList;
HashMap<String, ArrayList<String>> childList;
LayoutInflater inflater;
public CustomAdapter(Context context, ArrayList<String> groupList, HashMap<String, ArrayList<String>> childList) {
this.inflater = LayoutInflater.from(context);
this.groupList = groupList;
this.childList = childList;
}
@Override
public int getGroupCount() {
return groupList.size();
}
@Override
public int getChildrenCount(int i) {
return childList.get(groupList.get(i)).size();
}
@Override
public String getGroup(int i) {
return groupList.get(i);
}
@Override
public String getChild(int i, int i1) {
return childList.get(groupList.get(i)).get(i1);
}
@Override
public long getGroupId(int i) {
return i;
}
@Override
public long getChildId(int i, int i1) {
return 0;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public View getGroupView(int i, boolean b, View view, ViewGroup viewGroup) {
if(view == null) view = inflater.inflate(android.R.layout.simple_list_item_1, null);
TextView textView = view.findViewById(android.R.id.text1);
textView.setText(getGroup(i));
view.setTag("Group");
return view;
}
@Override
public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup) {
if(view == null) view = inflater.inflate(android.R.layout.simple_list_item_1, null);
TextView textView = view.findViewById(android.R.id.text1);
textView.setText(getChild(i, i1));
return view;
}
@Override
public boolean isChildSelectable(int i, int i1) {
return false;
}
}
In this sample, I use setTag() to identify the view is "Group". If you use different layouts for group view and child view, then you may use findViewById() to find a view that is inside the group view and so no changes in your adapter.
In addition, inside the try-catch, you can comment out the Toast() and enable the code elvMain.expandGroup(mainAdapter.getGroupCount() - 1);
which automatically expand the last group when the list is scrolled to the bottom, so the ExpandableListView becomes endless.
Hope that helps!