Yogesh Lakhotia Yogesh Lakhotia - 2 months ago 7
Android Question

RecyclerView not scrolling smothly

Recyclerview is not scrolling smoothly with scrollview. If i remove scrollview than its smooth. What should i do for smooth scroll of recyclerview?

<?xml version="1.0" encoding="utf-8"?>
<ScrollView
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="match_parent">

<RelativeLayout
android:id="@+id/content_activity_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>

<android.support.v7.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
/>

<LinearLayout
android:id="@+id/ll"
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_below="@+id/rv"
android:orientation="vertical">

<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:scaleType="fitXY"
/>

<TextView
android:id="@+id/textView35"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
/>

</LinearLayout>
</RelativeLayout>
</ScrollView>

Answer

You should not put your RecyclerView inside a ScrollView. If you need to show a footer at the end of your RecyclerView (i.e. a view after the last item of your RecyclerView) then this should also be part of the RecyclerView. To do this, you just need to specify a different item type in your adapter and return the appropriate ViewHolder.

First add this in your adapter:

private class ViewType {
      public static final int NORMAL = 0;
      public static final int FOOTER = 1;
}

Then, override the getCount() of your adapter and add one more item:

@Override
public int getCount() {
    return yourListsSize + 1;
}

Next, you need to specify of which type is the current item. To achieve this, override the getItemViewType() of your adapter:

@Override
public int getItemViewType(int position) {
    if(position == getCount() - 1)
        return ViewType.FOOTER;
    else
        return ViewType.NORMAL;
}

Finally, in the onCreateViewHolder() check the type of the current item and inflate the appropriate view:

@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {

    View rowView;

    switch (viewType) {
        case ViewType.NORMAL:
            rowView=LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.normal, viewGroup, false);
            break;
        case ViewType.FOOTER:
            rowView=LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.footer, viewGroup, false);
            break;
        default:
            rowView=LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.normal, viewGroup, false);
            break;
    }
    return new ViewHolder(rowView);
}

Of course, you would also need to move your footer layout in a separate xml file in order to inflate it here. By "footer layout", I'm referring to your LinearLayout with android:id="@+id/ll" and its child views.

Hope this helps.

Comments