I get weird scroll behavior when I add a RecyclerView inside a NestedScrollView.
It happens that whenever a scrollview has more lines than it can display on the screen, as soon as the action starts, the NestedScrollView starts with an offset from the top (image 1). If there are several elements in the scroll view so that they can be displayed immediately, this does not happen (image 2).
I am using support library version 23.2.0.
Image 1 : WRONG - Starts Offset From Above

Image 2 : CORRECT - several elements in the recycler view

I paste below my layout code:
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="fill_vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="10dp"> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Title:" style="@style/TextAppearance.AppCompat.Caption"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="@dimen/bodyPadding" style="@style/TextAppearance.AppCompat.Body1" android:text="Neque porro quisquam est qui dolorem ipsum"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Subtitle:" style="@style/TextAppearance.AppCompat.Caption"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" style="@style/TextAppearance.AppCompat.Body1" android:padding="@dimen/bodyPadding" android:text="Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit..."/> </LinearLayout> <android.support.v7.widget.RecyclerView android:id="@+id/rv" android:focusable="false" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> </android.support.v4.widget.NestedScrollView>
Am I missing something? Does anyone know how to fix this?
Update 1
It works correctly if I install the following code when initializing my activity:
sv.post(new Runnable() { @Override public void run() { sv.scrollTo(0,0); } });
Where sv is a link to NestedScrollView, however it looks like a hack.
Update 2
As requested, here is my adapter code:
public abstract class ArrayAdapter<T, VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> { private List<T> mObjects; public ArrayAdapter(final List<T> objects) { mObjects = objects; } public void add(final T object) { mObjects.add(object); notifyItemInserted(getItemCount() - 1); } public void clear() { final int size = getItemCount(); mObjects.clear(); notifyItemRangeRemoved(0, size); } @Override public int getItemCount() { return mObjects.size(); } public T getItem(final int position) { return mObjects.get(position); } public long getItemId(final int position) { return position; } public int getPosition(final T item) { return mObjects.indexOf(item); } public void insert(final T object, int index) { mObjects.add(index, object); notifyItemInserted(index); } public void remove(T object) { final int position = getPosition(object); mObjects.remove(object); notifyItemRemoved(position); } public void sort(Comparator<? super T> comparator) { Collections.sort(mObjects, comparator); notifyItemRangeChanged(0, getItemCount()); } }
And here is my ViewHolder:
public class ViewHolder extends RecyclerView.ViewHolder { private TextView txt; public ViewHolder(View itemView) { super(itemView); txt = (TextView) itemView; } public void render(String text) { txt.setText(text); } }
And here is the layout of each item in RecyclerView (it's just android.R.layout.simple_spinner_item - this screen is only for showing an example of this error):
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" style="?android:attr/spinnerItemStyle" android:singleLine="true" android:layout_width="match_parent" android:layout_height="wrap_content" android:ellipsize="marquee" android:textAlignment="inherit"/>