Search code examples
androidandroid-recyclerviewsortedlist

nested RecyclerView with SortedList shows nothing


I have a RecyclerView nested in a NestedScrollView and the adapter uses a SortedList to hold the content.

This is my layout:

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v4.widget.NestedScrollView
        marginTop="@{StatusbarUtils.getTopMargin(context)}"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

            <!-- some more ui elements -->

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

            <!-- some more ui elements -->

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

</FrameLayout>

And my adapter:

public class SettingsRecyclerViewAdapter extends RecyclerView.Adapter<SettingsRecyclerViewAdapter.ViewHolder> {

    @NonNull private final SortedList<Camera> cameras;

    public SettingsRecyclerViewAdapter(@NonNull final OnSettingsInteractionListener listener) {
        cameras = new SortedList<>(Camera.class, new CameraSortedListCallback(this));
    }

    public void addCamera(@NonNull final Camera camera) {
        cameras.add(camera);
    }

    private static class CameraSortedListCallback extends SortedListAdapterCallback<Camera> {

        private final RecyclerView.Adapter adapter;

        CameraSortedListCallback(final RecyclerView.Adapter adapter) {
            super(adapter);
            this.adapter = adapter;
        }

        @Override
        public int compare(final Camera o1, final Camera o2) {
            return 0;
        }

        @Override
        public boolean areContentsTheSame(final Camera oldItem, final Camera newItem) {
            return false;
        }

        @Override
        public boolean areItemsTheSame(final Camera item1, final Camera item2) {
            return false;
        }
    }
}

And how I uses it:

    final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
    linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    linearLayoutManager.setAutoMeasureEnabled(true);

    adapter = new SettingsRecyclerViewAdapter(this);

    recyclerView.setLayoutManager(linearLayoutManager);
    recyclerView.setHasFixedSize(true);
    recyclerView.setNestedScrollingEnabled(false);
    recyclerView.setAdapter(adapter);

When I use it and call addCamera(...) nothing happens :-(

The SortedListAdapterCallback has a onInserted method which calls mAdapter.notifyItemRangeInserted(position, count). When I override it and add adapter.notifyDataSetChanged() the RecyclerView shows the items.

    @Override
    public void onInserted(int position, int count) {
        Timber.i("onInserted() called with: " + "position = " + position + ", count = " + count);
        adapter.notifyDataSetChanged();
        super.onInserted(position, count);
    }

Is this a bug or did I do something wrong?


Solution

  • you need to remove the setHasFixedSize(true) call (default is false). If this is true, the recyclerview thinks its size doesn't change when you notify him, but this is not the case here ;)

    Hope this helps