15

There is a Recycler View inside the other Recycler View.Both needs to scroll vertically. Outer Recycler view is scrolling properly but inner recycler view is not.

Here is the code:

LinearLayoutManager mLayoutManager = new LinearLayoutManager(ViewActivity.this);
outerRecyclerView.setLayoutManager(mLayoutManager);
ViewAdapter adapter = new ViewAdapter(ViewActivity.this);
outerRecyclerView.setAdapter(adapter);

ViewAdapter is as follows:

public void onBindViewHolder(ViewAdapter.ViewViewHolder holder, int position)
{
  //RECYCLER VIEW
  //TODO: Inner Recycler view scroll movement
  LinearLayoutManager mLayoutManager = new LinearLayoutManager(context);
  holder.protocolRecyclerView.setLayoutManager(mLayoutManager);
  ViewProtocolAdapter adapter = new ViewProtocolAdapter(context);
  holder.protocolRecyclerView.setAdapter(adapter);
}

I have tried the following on both recycler views but could not solve the problem

recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
       @Override
       public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
           if(rv.getChildCount() > 0) {
               View childView = rv.findChildViewUnder(e.getX(), e.getY());
               if(childView ==listView) {
                   int action = e.getAction();
                   switch (action) {
                       case MotionEvent.ACTION_DOWN:
                           rv.requestDisallowInterceptTouchEvent(true);
                   }
               }
           }

           return false;
       }

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

       }

       @Override
       public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

       }
   });

Also tried this one:

outerRecyclerView.setNestedScrollingEnabled(true);//Does not make any difference
innerRecyclerView.setNestedScrollingEnabled(true);//Recycler View start scrolling but very slowly and sometimes scrolls the outer one.
Nav
  • 435
  • 1
  • 4
  • 15
  • They both need to scroll vertically? What kind of behavior do you expect? – cyroxis May 24 '16 at 21:06
  • can you try enable nested scrolling for the outside recycler and disable it for inner ? – Moh'd Awad May 24 '16 at 21:06
  • Having two nested views that scroll in the same direction is a really bad idea. Why do you need to do this? – Andrea Thacker May 24 '16 at 21:41
  • 1
    @DavidArgyleThackerActually I have expanding/collapsing kind of layout in recycler view. When the row of outer recycler view expands,it has another list to show which belongs to that particular row. That is why, I have two recycler views scrolling in the same direction. If you have better idea to accomplish this, please let me know. – Nav May 24 '16 at 22:37
  • if you want a expandable recycler view then you can try : https://github.com/thoughtbot/expandable-recycler-view – Harneev Jan 18 '17 at 12:21

10 Answers10

30

Apply this below ontouch listener to inner recycler which is may be in adapter of parent recycler.

RecyclerView.OnItemTouchListener mScrollTouchListener = new RecyclerView.OnItemTouchListener() {
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
    int action = e.getAction();
    switch (action) {
        case MotionEvent.ACTION_MOVE:
            rv.getParent().requestDisallowInterceptTouchEvent(true);
            break;
    }
    return false;
}

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

}

@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

}
}; 

innerrecyclerView.addOnItemTouchListener(mScrollTouchListener);
Manthan Patel
  • 1,784
  • 19
  • 23
5

I had the same problem while implementing a recycler view some time ago. Both the recycler views would start scrolling, right. Though it's a bad idea going for a nested recycler view but if you want it to scroll properly, you have to disable the scroll on the inner one. I am not sure but i think it was this. Let me know if it works. If not I'll dig up my code and try to find the solution.

RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(parent.getContext()) {
            @Override
            public boolean canScrollVertically() {
                return false;
            }
        };
mysticfyst
  • 347
  • 4
  • 9
  • Okay. The way I did it was to make the **inner** recycler view unscrollable. So while scrolling, only the outer one was active. Here is a piece of that code. ` RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(parent.getContext()) { @Override public boolean canScrollVertically() { return false; } }; innerRecyclerView.setLayoutManager(mLayoutManager);` Now this code is in the **onCreateViewHolder()** of the first recycler view adapter (outer recycler view). – mysticfyst Jun 17 '16 at 03:52
2

Instead of using ScrollView use android.support.v4.widget.NestedScrollView

Here for me it worked perfectly.

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="4dp"
            />

</android.support.v4.widget.NestedScrollView>
0

Now, for this to work you need to disable vertical scroll of sublist recycler view.

LinearLayoutManager layoutManager = new LinearLayoutManager(context) {
            @Override
            public boolean canScrollVertically() {
                return false;
            }
    }; 
0
parentScroll.setOnTouchListener(new View.OnTouchListener() {

    public boolean onTouch(View v, MotionEvent event) {

        findViewById(R.id.childScroll).getParent()
           .requestDisallowInterceptTouchEvent(false);

        return false;
     }
});

childScroll.setOnTouchListener(new View.OnTouchListener() {

      public boolean onTouch(View v, MotionEvent event) {  

           v.getParent().requestDisallowInterceptTouchEvent(true);
           return false;
      }
});
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
  • 2
    While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – Suraj Rao Jun 21 '19 at 09:59
0

For homever might work, i made a few things i saw arround some posts.

First i made a custom LinearLayoutManager blocking vertical scroll.

    class CustomHorizontalLinearLayout(context: Context) :
LinearLayoutManager(context, RecyclerView.HORIZONTAL, false) {

override fun canScrollVertically(): Boolean {
    return false
}

And set it to the child RecyclerView (which in this case it's called recommendationRV):

itemView.recommendationRV?.apply {
                adapter = recyclerViewAdapter
                setRecycledViewPool(viewPool)
                setLayoutManager(layoutManager)
                setHasFixedSize(true)
            }

Next I added an external NestedScrollView to the child RecyclerView ViewHolder XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="220dp"
android:orientation="vertical"
android:background="@color/transparent"
android:paddingVertical="10dp">

<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recommendationRV"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/transparent"
        android:clickable="true"
        android:focusable="true"
        />
</androidx.core.widget.NestedScrollView>

And this seemed to work. It's probably not the best approach but it worked like a charm for me so i hope this can help somebody

0

try using this code, it works for me

<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:isScrollContainer="true">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

 </androidx.core.widget.NestedScrollView>
-2

What you can do is, you can add a scroll view as root layout for the view holder encapsulating second recycler view in it.

  <ScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/subContainer"
    >
    <android.support.v7.widget.RecyclerView
        android:id="@+id/subList"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
         />
</ScrollView>

After doing that, subList recycler view can fully utilize wrap_content property. Now, for this to work you need to disable vertical scroll of sublist recycler view.

LinearLayoutManager layoutManager = new LinearLayoutManager(context) {
        @Override
        public boolean canScrollVertically() {
            return false;
        }
    }; 

Doing so, all the vertical scroll events will be handled by parent recycler view.

-2

Don't keep a recycler view inside a recycler view. Instead you should inflate the inner recycler view. You can have a Linear layout and inflate that layout in onBindViewHolder of the recycler view. By doing this, you will never face scrolling problem.

Arpit Gupta
  • 113
  • 1
  • 6
-3

You don't need to put recyclerView inside another recyclerView. This does not make sense. If you want to put together in a single Layout XML just follow the steps below:

  • Make NestedScrollView parent
  • Create LinerLayout inside your NestedScrollView
  • Put RecyclerViews inside NestedScrollView

    <android.support.v4.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <LinearLayout
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
    
                <android.support.v7.widget.RecyclerView
                    android:id="@+id/firstRecycler"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"/>
    
                <android.support.v7.widget.RecyclerView
                    android:id="@+id/secondRecycler"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"/>
    
            </LinearLayout>
    </android.support.v4.widget.NestedScrollView>