0

I am implementing nested RecyclerView in my app, where a vertical Recycler holds another Recycler as its item. Everything is working fine I get the desired views. But I also need to add Sync Scrolling to these views. Which I have done so. The problem that I am facing is when the number of nested lists is only as big as 5-6 I get StackOverflowError while scrolling. Here's what I followed in adding sync scrolling to my app.

I understand you get StackOverfloError when there are too many nested RecyclerViews, but what I don't get is how are even 5-6 RecyclerViews too many. (I may need at sometime as many as 30 RecyclerViews) but that is neither here nor there. However at any given time there are a maximum of 7 views displayed at any given time.

Here is my RecyclerView layout file item_layout.xml.

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:visibility="visible">

<android.support.v7.widget.RecyclerView
    android:id="@+id/programList"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFFFFF"
    android:visibility="gone"/>
<TextView
    android:id="@+id/noEpgMessage"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:textSize="20sp"
    android:textColor="#FFFFFF"
    android:text="@string/no_epg_found"
    android:gravity="left"
    android:visibility="gone"/>

Within this RecyclerView I have the following items in item.xml.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingRight="1dp">

<TextView
    android:id="@+id/epgProgramItem"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:textColor="#000000"
    android:textSize="16sp"
    android:ellipsize="marquee"
    android:marqueeRepeatLimit="marquee_forever"
    android:gravity="center_vertical|left"
    android:background="@drawable/epg_program_background"/>

Here is my Sync Scrolling code in ViewHolder.java.

recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {

            private int mLastY;
            @Override
            public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
                Log.d(TAG, "ProgramsList: onInterceptTouchEvent()");

                if (rv.getScrollState() == RecyclerView.SCROLL_STATE_IDLE) {
                    onTouchEvent(rv, e);
                }

                return false;
            }

            @Override
            public void onTouchEvent(RecyclerView rv, MotionEvent e) {

                final int action = e.getAction();

                if (action == MotionEvent.ACTION_DOWN) {

                    mLastY = rv.getScrollY();
                    Log.d("ListenerAddRemove", "Listener for " + rv.getTag() + " added");
                    rv.addOnScrollListener(selfRemovingListener);
                }
                else if (action == MotionEvent.ACTION_UP && rv.getScrollY() == mLastY) {

                    Log.d("ListenerAddRemove", "Removed");
                    rv.removeOnScrollListener(selfRemovingListener);
                }
            }

            @Override
            public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

            }
        });


private final RecyclerView.OnScrollListener selfRemovingListener = new SelfRemovingOnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, 0);

            scrollAll(recyclerView, dx, 0);
        }
    };

public void scrollAll(RecyclerView rv, int dx, int dy) {

    Log.d(TAG, "Calling Recycler Tag : " + String.valueOf(rv.getTag()));

    Log.d(TAG, "ScrollAll()");
    for (int i = 0; i < ((recyclerList != null) ? recyclerList.size(): 0); i++) {

        RecyclerView current = recyclerList.get(i);

        if (current != rv) {
            Log.d(TAG, "Current RecyclerView Tag : " + String.valueOf(current.getTag()));
            current.scrollBy(dx, dy);
        }
    }
}

And my SelfRemovingOnScrollListener.java.

public class SelfRemovingOnScrollListener extends RecyclerView.OnScrollListener {

@Override
public final void onScrollStateChanged(@NonNull final RecyclerView recyclerView, final int newState) {
    super.onScrollStateChanged(recyclerView, newState);
    if (newState == RecyclerView.SCROLL_STATE_IDLE) {
        Log.d("ListenerAddRemove", "Self Removing Listener Removed");
        recyclerView.removeOnScrollListener(this);
    }
}

}

So here are my questions.

  • How do I get around this i.e, if there is a way around it?
  • Is there something else I can do to get the same functionality?
  • How many RecyclerViews can I safely use with letting the application crash?

I've read the following link and it doesn't help me much.

Community
  • 1
  • 1
Abbas
  • 3,529
  • 5
  • 36
  • 64
  • your approach is wrong: instead of making nested and synchronized `RecycleView`s you should use appropriate `RecyclerView.LayoutManager` – pskink Dec 22 '15 at 07:25
  • @pskink Well I sought for `StaggeredLayoutManager` at first but then I realized it doesn't support vertical and horizontal scrolling at the same time. So I had to move from that. – Abbas Dec 22 '15 at 07:30
  • so, use the one that supports vertical and horizontal scrolling at the same time – pskink Dec 22 '15 at 07:31
  • I probably should have mentioned this but I need SyncScrolling not only horizontally but vertically too. – Abbas Dec 22 '15 at 07:31
  • @pskink Could u suggest one? – Abbas Dec 22 '15 at 07:35
  • i saw at least 2 such layout managers but dont remember where it was – pskink Dec 22 '15 at 07:38
  • @pskink but RecyclerView provides only three layout managers `LinearLayoutManager`, `GridLayoutManager` and `StaggeredLayoutManager` – Abbas Dec 22 '15 at 07:40
  • it provides also `android.support.v7.widget.RecyclerView.LayoutManager` – pskink Dec 22 '15 at 07:45
  • @pskink So you are suggesting I should make my own `LayoutManager`? Ok fine I can do that but it still doesn't answer my 3rd question. – Abbas Dec 22 '15 at 07:49
  • `How many RecyclerViews can I safely use ...` ? you will have only one `RecyclerView`... – pskink Dec 22 '15 at 07:51
  • @pskink For now ofcourse but, I'd like to know how many `RecyclerView`s can be used. And if the number depends on a device and its resources then I'd like to know which ones. – Abbas Dec 22 '15 at 07:54

0 Answers0