简体   繁体   中英

Recycler View Inside Recycler View not Scrolling

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.

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);

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;
            }
        };

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>

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.

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;
            }
    }; 

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.

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;
      }
});

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

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>

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM