9

I have a layout which has a CardView and a FloatingActionButton associated with it. There is a list of replies below the CardView (which is a RecyclerView). Sometimes the CardViews' height is greater than the screen, so I have used layout_height="wrap_content" for the CardView and wrapped the whole LinearLayout inside a ScrollView.

However, this causes a problem(since it is a scrolling view inside a ScrollView) while scrolling the items of the RecyclerView. As suggested in some of the questions and answers posted, I have used both the NestedScrollView and the android:nestedScrollingEnabled="true" tag but the scrolling in the RecyclerView is still bad.

Here is my Layout file -

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    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"
    tools:context="com.example.forum.reply.ReplyActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <android.support.v7.widget.Toolbar
            android:id="@+id/reply_toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?attr/colorPrimary"
            android:minHeight="?attr/actionBarSize"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:titleTextColor="@android:color/white"/>

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:nestedScrollingEnabled="true"
            android:fillViewport="true">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="8dp"
                android:orientation="vertical">

                <android.support.v7.widget.CardView
                    android:id="@+id/topic_card"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:paddingBottom="@dimen/card_margin"
                    android:paddingLeft="@dimen/card_margin"
                    android:paddingRight="@dimen/card_margin"
                    android:paddingTop="@dimen/card_margin">

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:orientation="vertical"
                        android:paddingEnd="@dimen/card_margin"
                        android:paddingStart="@dimen/card_margin">

                        <android.support.v7.widget.AppCompatTextView
                            android:id="@+id/topic_title"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:layout_marginBottom="8dp"
                            android:layout_marginTop="8dp"
                            android:textAppearance="@style/TextAppearance.AppCompat.Title"/>

                        <android.support.v7.widget.AppCompatTextView
                            android:id="@+id/topic_content"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:textAppearance="@style/TextAppearance.AppCompat.Body1"/>
                    </LinearLayout>
                </android.support.v7.widget.CardView>

                <ProgressBar
                    android:id="@+id/reply_progressbar"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:indeterminate="true"
                    android:visibility="visible"/>

                <android.support.v7.widget.RecyclerView
                    android:id="@+id/list_of_replies"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:visibility="invisible"/>
            </LinearLayout>
        </ScrollView>
    </LinearLayout>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/reply_to_topic"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:clickable="true"
        android:src="@drawable/ic_reply_white_24dp"
        app:layout_anchor="@id/topic_card"
        app:layout_anchorGravity="bottom|right|end"/>

</android.support.design.widget.CoordinatorLayout>

Here are some images -

CardView with FloatingActionButton visible

Scrolling from the CardView to RecyclerView is smooth

Scrolling down isn't smooth

Scrolling up also isn't smooth

Community
  • 1
  • 1
yadav_vi
  • 1,289
  • 4
  • 16
  • 46

6 Answers6

28

When you have multiple scrolling Views in your layout (eg. RecyclerView + ScrollView) and when you scroll while in your recyclerView, the recyclerView scrolls with the parent Scrollview. this causes jitters in RecyclerView. You can avoid this jitter by the following.

You can add
android:nestedScrollingEnabled="false" to your RecyclerView in XML or
recyclerView.setNestedScrollingEnabled(false); to your RecyclerView in Java.

Siddhesh Dighe
  • 2,894
  • 3
  • 16
  • 16
  • 1
    Can you explain why this works? Also, I have to support devices older than API v21. – yadav_vi Jun 19 '16 at 16:49
  • 2
    You have multiple scrolling Views in your layout, so when you scroll while touching your recyclerView, the recyclerView scrolls with the parent Scrollview. this causes jitters in RecyclerView, so with nestedScrollingEnabled="false" you kinda stop the scroll of recyclerView and the only scroll which is triggered is from the parent ScrollView. Also i do this programmatically with .setNestScrollingEnabled() and works fine for me on device older than API v21. – Siddhesh Dighe Jun 20 '16 at 06:38
  • 1
    I have accepted the answer but could you update it with the things that you have mentioned in the comment. – yadav_vi Jun 20 '16 at 07:38
  • because off above line my last card view is cutting off – Rahul Chaudhary Jul 06 '16 at 10:39
  • 6
    Note that if you want to support devices older than v21 you have to use `ViewCompat.setNestedScrollingEnabled(mRecyclerView, false);` @yadav_vi – marios-codes Sep 20 '17 at 12:21
10

If you want to support devices older than api 21 then you should use

ViewCompat.setNestedScrollingEnabled(mRecyclerView, false);

in your Activity/Fragment

marios-codes
  • 159
  • 2
  • 9
  • 1
    Can you please explain why my answer is wrong and I got down voted? I would like to know if I am mistaken, because I use the above snippet in my code and it works just fine. Thank you – marios-codes Sep 21 '17 at 14:34
3

You have to do multiple tasks:

  1. put your recyclerview inside a android.support.v4.widget.NestedScrollView instead of normal ScrollView
  2. set your recyclerview android:nestedScrollingEnabled="true" in layout XML file
  3. to support devices older than API 21 then you should use ViewCompat.setNestedScrollingEnabled(mRecyclerView, false) in your code
  4. set your RecyclerView height to android:layout_height="wrap_content" (or width if it is horizontal!)
Mohsen Mirhoseini
  • 8,454
  • 5
  • 34
  • 59
3

Besides Setting the android:nestedScrollingEnabled="false" you need to make sure that the parent of the RecyclerView is a android.support.v4.widget.NestedScrollView

I had troubles that the RecyclerView did not measure properly (on big screens) when it was in a standard ScrollView

cwiesner
  • 934
  • 1
  • 8
  • 24
1

if you want to scroll RecyclerView inside ScrollView and ScrollView prevents from scrolling RecyclerView (in API 16 this occurred) you should use android.support.v4.widget.NestedScrollView instead of ScrollView and also you must set nestedScrollView.setNestedScrollingEnabled(false); by this way you can prevent from scrolling nestedScrollView when you scroll RecyclerView. hope this help some one

0

I have this problem ,solving it with : custom ScrollView and override onInterceptTouchEvent to return false.

hope it's help someone/

Guy
  • 133
  • 2
  • 11