Witam mam taki problem, że mam zagęszczone listy - przedstawię to w formie schematu Fragment > RecyclerView > ListItem (który ma w sobie właśnie layout itemu i kolejny RecyclerView) i tak jest to zagęszczone i tak, wszystko fajnie działa oprócz jednej rzeczy. Adapter dostaje dane z database, i nie ma jak sprawdzić czy jest item inserted czy deleted czy moved więc dawałem notifyDataSetChanged(), ale zauważyłem teraz, że gdy itemów jest więcej niż ekran i trzeba przewijać w dół to gdy się cokolwiek doda i tak cofa do góry na sam początek a wszystko co było zwinięte lub rozwinięte rozwija się od nowa. Wyczytałem że VIewHoldery tworzą się wtedy od nowa.
Tak więc chciałem początkowo użyć Callbacku z diffUtil ale nowe adaptery tworzę dynamicznie, nie przechowuje instancji więc nic mi to nie dało... Nie wiem może ktoś ma pomysł jakby to zrobić?

Niżej troszkę kodu, całość na https://github.com/Xezolpl/My-Library

To jest adapter od notatek, notatki siedzą w chapter'ach dlatego ViewHolder jest ChapterNoteViewHolder - dla tych i dla tych gdyż różnią się minimalnie (chapters mają 2 recViewy - jeden na notki jeden na cytaty)

public class NotesRecViewAdapter extends RecyclerView.Adapter<ChaptersNotesViewHolder> {

    private List<Note> notes = new ArrayList<>();
    private List<ChaptersNotesViewHolder> viewHolders = new ArrayList<>();
    private Context context;
    private LayoutInflater inflater;

    NotesRecViewAdapter(Context context) {
        this.context = context;
        this.inflater = LayoutInflater.from(context);
    }

    void setNotesList(List<Note> notes) {
            final NoteDiffCallback callback = new NoteDiffCallback(this.notes, notes);
            final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(callback);

            this.notes.clear();
            this.notes.addAll(notes);
            diffResult.dispatchUpdatesTo(this);
    }

    List<ChaptersNotesViewHolder> getViewHolders() {
        return viewHolders;
    }

    @NonNull
    @Override
    public ChaptersNotesViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = inflater.inflate(R.layout.listitem_note, parent, false);
        ChaptersNotesViewHolder viewHolder = new ChaptersNotesViewHolder(v, context, ChaptersNotesViewHolder.FROM_NOTE);
        viewHolders.add(viewHolder);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ChaptersNotesViewHolder holder, int position) {
        holder.setData(notes.get(position), position);
    }

    @Override
    public int getItemCount() {
        return notes.size();
    }

}
ChaptersNotesViewHolder(@NonNull View itemView, Context context, int parent) {
        super(itemView);
        this.context = context;
        this.parent = parent;
        activity = (FragmentActivity) context;

        initWidgets();
        setOnClickListeners();

        if (parent == FROM_CHAPTER) {
            quotesAdapter = new QuotesRecViewAdapter(context);
            quotesRecView.setLayoutManager(new GridLayoutManager(context, 1));
        }

        adapter = new NotesRecViewAdapter(context);
    }

    private void initWidgets() {

        textView = itemView.findViewById(R.id.textView);
        recView = itemView.findViewById(R.id.recView);
        wholeRelLay = itemView.findViewById(R.id.wholeRelLay);
        if (parent == FROM_NOTE) {
            marker_imgView = itemView.findViewById(R.id.marker_imgView);
        } else {
            quotesRecView = itemView.findViewById(R.id.quotes_recView);
            quotesRecView.setVisibility(View.GONE);
        }
        moreBtn = itemView.findViewById(R.id.moreBtn);
        setRecViewVisible(true);

    }

    private void setOnClickListeners() {

        wholeRelLay.setOnClickListener(view -> {
            if (isRecViewVisible) {
                setRecViewVisible(false);
                if (parent == FROM_CHAPTER) setQuotesViewVisible(false);
            } else {
                setRecViewVisible(true);
                if (parent == FROM_CHAPTER) setQuotesViewVisible(true);
            }
        });

        wholeRelLay.setOnLongClickListener(view -> {
            expandWithChildren(!isRecViewVisibleWithChildren);
            return true;
        });

        moreBtn.setOnClickListener(view -> {

            PopupMenu popupMenu = new PopupMenu(context, view);
            popupMenu.inflate(R.menu.chapter_note_popup_menu);
            if (parent == FROM_NOTE) {
                popupMenu.getMenu().getItem(2).setVisible(false);
            }else{
                popupMenu.getMenu().getItem(1).setTitle("Edit chapter");
                popupMenu.getMenu().getItem(3).setTitle("Delete chapter");
            }
            popupMenu.setOnMenuItemClickListener(menuItem -> {
                switch (menuItem.getItemId()) {
                    case R.id.addMenuBtn: {

                        Intent intent = new Intent(context, AddNoteActivity.class);
                        if (parent == FROM_CHAPTER) {
                            intent.putExtra("chapter", parentChapter);
                            intent.putExtra("parent", FROM_CHAPTER);
                            setQuotesViewVisible(true);
                        } else {
                            intent.putExtra("note", parentNote);
                            intent.putExtra("parent", FROM_NOTE);
                        }
                        context.startActivity(intent);
                        setRecViewVisible(true);
                        break;
                    }
                    case R.id.editMenuBtn: {

                        Intent intent;
                        if (parent == FROM_CHAPTER) {
                            intent = new Intent(context, AddChapterActivity.class);
                            intent.putExtra("chapter", parentChapter);
                        } else {
                            intent = new Intent(context, AddNoteActivity.class);
                            intent.putExtra("note", parentNote);
                            intent.putExtra("parent", EDITION);
                        }

                        context.startActivity(intent);
                        break;
                    }
                    case R.id.insertQuoteMenuBtn: {

                        Intent intent = new Intent(context, InsertQuoteActivity.class);
                        intent.putExtra("chapter", parentChapter);
                        setRecViewVisible(true);
                        setQuotesViewVisible(true);
                        context.startActivity(intent);
                        break;
                    }
                    case R.id.deleteMenuBtn: {
                        DeletingManager deletingManager = new DeletingManager((AppCompatActivity) context);

                        if (parent == FROM_CHAPTER) {
                            deletingManager.showDeletingDialog(context.getString(R.string.del_chapter),
                                    context.getString(R.string.delete_chapter),
                                    DeletingManager.CHAPTER,
                                    parentChapter);
                        } else {
                            deletingManager.showDeletingDialog(context.getString(R.string.del_note),
                                    context.getString(R.string.delete_note),
                                    DeletingManager.NOTE,
                                    parentNote);
                        }
                        break;
                    }
                    default:
                        return false;
                }
                return true;
            });

            MenuPopupHelper menuHelper = new MenuPopupHelper(context, (MenuBuilder) popupMenu.getMenu(), view);
            menuHelper.setForceShowIcon(true);
            menuHelper.show();
        });

    }

    void setData(Chapter chapter) {

        parentChapter = chapter;
        textView.setText(chapter.getName());
        NoteViewModel noteModel = ViewModelProviders.of(activity).get(NoteViewModel.class);
        noteModel.getNotesByParent(chapter.getId()).observe(activity, notes -> {
                    adapter = new NotesRecViewAdapter(context);
                    adapter.setNotesList(notes);
                    recView.setAdapter(adapter);
                    recView.setLayoutManager(new GridLayoutManager(context, 1));

                    QuoteViewModel quoteViewModel = ViewModelProviders.of(activity).get(QuoteViewModel.class);
                    quoteViewModel.getQuotesByChapter(parentChapter.getId()).observe(activity, quotes -> {
                        quotesAdapter.setQuotes(quotes);
                        quotesRecView.setAdapter(quotesAdapter);
                    });
                }
        );
    }

    void setData(Note note, int position) {

        parentNote = note;
        textView.setText(note.getNote());
        try {
            Drawable drawable;
            int markerType = note.getMarkerType();

            if (markerType == Markers.NUMBER_MARKER || markerType == Markers.LETTER_MARKER) {
                drawable = Markers.getLetterMarker(markerType, position, note.getColor());
            } else {
                drawable = Markers.getSimpleMarker(context, note.getMarkerType(), note.getColor());
            }
            marker_imgView.setImageDrawable(drawable);
        } catch (IOException e) {
            e.printStackTrace();
        }
        NoteViewModel noteModel = ViewModelProviders.of(activity).get(NoteViewModel.class);
        noteModel.getNotesByParent(note.getId()).observe(activity, notes -> {
            adapter.setNotesList(notes);
            recView.setAdapter(adapter);
            recView.setLayoutManager(new GridLayoutManager(context, 1));
        });
    }

    private void setRecViewVisible(boolean b) {
        if (b) {
            recView.setVisibility(View.VISIBLE);
            isRecViewVisible = true;
        } else {
            recView.setVisibility(View.GONE);
            isRecViewVisible = false;
        }
    }

    private void setQuotesViewVisible(boolean b) {
        quotesRecView.setVisibility(b ? View.VISIBLE : View.GONE);
    }

    public void expandWithChildren(boolean b) {
        for (ChaptersNotesViewHolder viewHolder : adapter.getViewHolders()) {
            viewHolder.expandWithChildren(b);
        }
        setRecViewVisible(b);
        isRecViewVisibleWithChildren = b;

    }
}

No i sam callback

public class NoteDiffCallback extends DiffUtil.Callback {
    private List<Note> newNotes;
    private List<Note> oldNotes;

    public NoteDiffCallback(List<Note> newNotes, List<Note> oldNotes) {
        this.newNotes = newNotes;
        this.oldNotes = oldNotes;
    }

    @Override
    public int getOldListSize() {
        return oldNotes.size();
    }

    @Override
    public int getNewListSize() {
        return newNotes.size();
    }

    @Override
    public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
        return oldNotes.get(oldItemPosition).getId().equals(newNotes.get(newItemPosition).getId());
    }

    @Override
    public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
        Note oldN = oldNotes.get(oldItemPosition);
        Note newN = newNotes.get(newItemPosition);
        return oldN.getMarkerType() == newN.getMarkerType() &&
                oldN.getColor() == newN.getColor() &&
                 oldN.getNote().equals(newN.getNote());
    }
}