1

I want my app to auto-scroll at particularGroup in ExpandableList when a user selects a particular group name from RecyclerView. I am using the Interface to handle the click from RecyclerView

here is my mainActivity code:

 @Override
public void onItemClick(int position) {
    menuListForRestaurant.setVisibility(View.GONE);
    if (!menuOpenChecker){
        menuOpenChecker=true;
    }else{
        menuOpenChecker=false;
    }
    //The above code gets execute except for the below one
   listView.smoothScrollToPosition(position);// this line is not executing
}

@SuppressLint("ClickableViewAccessibility")
private void ListViewAdapter(final HashMap<String, ArrayList<ProductList>> objectMap, final ArrayList<String> headerList) {

    listViewAdapter= new RestaurantItemListView(RestaurantDetail.this.getApplicationContext(), objectMap,headerList);
    listView.setAdapter(listViewAdapter);
    listViewAdapter.notifyDataSetChanged();
}

private void RecyclerMenuView(ArrayList<String> headerList){
    menuItemRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    menuItemRecyclerView.getRecycledViewPool().clear();
    menuAdapterRecyclerView= new RestaurantMenuRecyclerView(headerList, this.getApplicationContext());
    menuItemRecyclerView.setItemAnimator(new DefaultItemAnimator());
    menuItemRecyclerView.setAdapter(menuAdapterRecyclerView);
    menuAdapterRecyclerView.notifyDataSetChanged();
    menuAdapterRecyclerView.setOnClick(RestaurantDetail.this);

}

Its like the line which I have mentioned as not working because it doesn't get updated at the ExpandableListView

Thank you in Advance please anyone??

Athos Tokbi
  • 177
  • 11
  • Checked this one out ? https://stackoverflow.com/questions/63621451/how-to-set-vertical-animation-scrolling-in-android-application/63622180#63622180 – Laurentiu Daniel Aug 29 '20 at 09:31
  • @LaurentiuDaniel I am not clicking directly on the ExpandableListView, since the Header which I have in RecyclerListView has the same position as for ExpandableListView, So I am clicking the it on RecyclerView getting the position and directly declaring it on the Method. – Athos Tokbi Aug 29 '20 at 09:40
  • which is not working – Athos Tokbi Aug 29 '20 at 09:43
  • which you are pointing out is for directly clicking on the header which is not the case here – Athos Tokbi Aug 29 '20 at 09:45
  • 1
    Pls note that **smoothScrollToPosition** only makes the item view into visible area. If the view is already visible, there is no scroll. You can try **smoothScrollToPositionFromTop(position, 0)**. On the other hand, the view position in ExpandableListView also counts the child views, e.g. smoothScrollToPositionFromTop(1, 0) will scroll to group 1 header when group 0 is not expanded, but scroll to child 1 of group 0 when group 0 is expanded. Therefore position for ExpandableListView may be different from RecyclerView. – i_A_mok Sep 02 '20 at 13:11
  • @i_A_mok I can use it in the MainActivity right??, no need to write it inside the Adapter.! – Athos Tokbi Sep 02 '20 at 15:53
  • I tried inside the adapter and even the MainActivity the `.smoothScrollToPositionFromTop() `is not working. – Athos Tokbi Sep 02 '20 at 16:04

2 Answers2

1

As you are using NonScrollExpandableListView, so the ExpandableListView does not scroll. Here I show 3 possible solutions:

  1. 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>
  1. 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.
i_A_mok
  • 2,536
  • 2
  • 9
  • 13
1

I have Finally resolved issue by using simeple code below:

//AutoScroll for menu
    int t = 0,j, e=0, l=0;

    for (int n=0; n<=position;n++){

        e= e +objectMap.get(textHeaderlist.get(n)).size();
        l= l+450;
    }

    t=position+1;

    j= 200+e+t+l;
    scrollView.scrollTo(5, j);

which finally resolve my issue.

Either way, thank you!

Athos Tokbi
  • 177
  • 11