As you are using NonScrollExpandableListView, so the ExpandableListView does not scroll. Here I show 3 possible solutions:
NonScrollExpandableListView and ScrollView (your current approach): Instead of scroll the ExpandableListView, you have to scroll the ScrollView. It will be very difficult to calculate the scroll position if there is any group in the ExpandableListView expanded. Therefore it is much easier to collapse all groups and then expands only the desired group. Code is like this (I have not tested it):
for (int i = 0; i < listViewAdapter.getGroupCount(); i++) listView.collapseGroup(i);
int a = header.getHeight(); // header refers to all views above the ExpandableListView.
a += (listViewAdapter.getGroupView(0, false, null, null).getHeight() + listView.getDividerHeight())*
position;
scrollView.smoothScrollTo(0, a);
listView.expandGroup(position);
2.ExpandableListView with header (NoScrollView): Start a new project and try this sample, verify if it meets your requirements. Here I used Spinner instead of RecyclerView.
MainActivity.java:
public class MainActivity extends AppCompatActivity {
LinkedHashMap<String, ArrayList<String>> dataList;
ExpandableListView expandableListView;
CustomBaseExpandableListAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dataList = createSampleList();
expandableListView = findViewById(R.id.expandable_list_view);
adapter = new CustomBaseExpandableListAdapter(getApplicationContext(), dataList);
expandableListView.setAdapter(adapter);
View header = getLayoutInflater().inflate(R.layout.header, null);
Button btExpand = header.findViewById(R.id.bt_expand);
btExpand.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
for (int i = 0; i < adapter.getGroupCount(); i++) expandableListView.expandGroup(i);
}
});
Spinner spinner = findViewById(R.id.selector);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(getApplication(), android.R.layout.simple_list_item_1,
new ArrayList<>(dataList.keySet()));
spinner.setAdapter(arrayAdapter);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
int a = 1; // Without header a=0, with header a=1.
for (int j = 0; j < i; j++) {
a += (expandableListView.isGroupExpanded(j) ? adapter.getChildrenCount(j) : 0) + 1;
}
// expandableListView.smoothScrollToPosition(a);
expandableListView.smoothScrollToPositionFromTop(a, 0);
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
expandableListView.addHeaderView(header);
}
private LinkedHashMap<String, ArrayList<String>> createSampleList() {
LinkedHashMap<String, ArrayList<String>> dataList = new LinkedHashMap<>();
for (int i = 0; i < 10; i++) {
ArrayList<String> childList = new ArrayList<>();
for (int j = 0; j < 17; j++) {
childList.add("Item " + i + "-" + j);
}
dataList.put("Group " + i, childList);
}
return dataList;
}
}
CustomBaseExpandableListAdapter.java:
public class CustomBaseExpandableListAdapter extends BaseExpandableListAdapter {
ArrayList<String> groupList;
LinkedHashMap<String, ArrayList<String>> dataList;
Context context;
public CustomBaseExpandableListAdapter(Context context, LinkedHashMap<String, ArrayList<String>> dataList) {
this.context = context;
this.dataList = dataList;
groupList = new ArrayList(dataList.keySet());
}
@Override
public int getGroupCount() {
return groupList.size();
}
@Override
public int getChildrenCount(int i) {
return dataList.get(groupList.get(i)).size();
}
@Override
public String getGroup(int i) {
return groupList.get(i);
}
@Override
public String getChild(int i, int i1) {
return dataList.get(groupList.get(i)).get(i1);
}
@Override
public long getGroupId(int i) {
return 0;
}
@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) {
TextView textView;
if (view == null) {
textView = new TextView((context));
textView.setTextSize(30);
textView.setPadding(80, 0, 0, 0);
} else {
textView = (TextView) view;
}
textView.setText(getGroup(i));
return textView;
}
@Override
public View getChildView(int i, int i1, boolean b, View view, ViewGroup viewGroup) {
TextView textView;
if (view == null) {
textView = new TextView((context));
textView.setTextSize(20);
textView.setPadding(120, 0, 0, 0);
} else {
textView = (TextView) view;
}
textView.setText(getChild(i, i1));
return textView;
}
@Override
public boolean isChildSelectable(int i, int i1) {
return true;
}
}
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">
<Spinner
android:id="@+id/selector"
android:layout_marginLeft="10dp"
android:layout_width="match_parent"
android:layout_height="50dp"/>
<ExpandableListView
android:id="@+id/expandable_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
header.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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
app:srcCompat="@drawable/ic_launcher_foreground" />
<Button
android:id="@+id/bt_expand"
android:layout_width="50dp"
android:layout_height="50dp"
android:text="+"
android:textSize="30dp" />
</LinearLayout>
- ExpandableListView using ViewPager as child view (ExpandableListView with ViewPager combination as its child), ExpandableListView using HorizontalRecyclerView as child view (Expandable list view with HorizontalScroll View for child view): With one of these approachs and set
OnGroupExpandListener
of the ExpandableListView to expand only one group, then I think that the current RecyclerView in not necessary.