📝 Description
When returning from NoteEditActivity to MainActivity, the app currently reloads the entire note list, resulting in a noticeable jump (especially in GridView layout) and UI lag before the list becomes usable. This negatively impacts user experience, particularly with many notes or when the ReleaseNote header is visible.
🔍 Observed behavior
- After closing
NoteEditActivity, noteViewModel.loadNotes() is called in MainActivity.
- This triggers the observer for
notesLiveData, which in turn calls noteAdapter.updateNotes(...).
- That invokes
DiffUtil.calculateDiff(...) internally, causing the entire adapter content to be recalculated.
- Then,
recyclerView.scrollToPosition(...) is called to restore the previous scroll position.
- This entire sequence happens on the UI thread, leading to stuttering and visible jumping.
- With
StaggeredGridLayoutManager, layouting is especially expensive.
⚠️ Root cause
loadNotes() always loads the full note list, even when only one note was edited or created.
- This causes a full rebind in the adapter, triggering layout invalidation.
- Scroll restoration occurs too early, before RecyclerView has finished layouting.
- The
ReleaseNote header is reset on every return, even if unchanged → triggers layout recalculation.
✅ Expected behavior
- Only update the changed or new note in the list (e.g., via
updateSingleNote(...)).
- Avoid full list reload unless necessary.
- Restore scroll position only after RecyclerView layout is complete, ideally without expensive
ViewTreeObserver.
- Only update the
ReleaseNote header if its content actually changed.
✅ Suggested solution (for next version)
1. Add updateSingleNote(Note note) method in NoteViewModel
- Replaces the matching note in the
notesLiveData list.
- Triggers a minimal update via
setValue().
2. In NoteEditActivity
- Add the updated note to the result
Intent:
intent.putExtra("updated_note", note);
setResult(RESULT_OK, intent);
3. In MainActivity
- Handle the updated note in
ActivityResultLauncher:
if (result.getResultCode() == RESULT_OK) {
Intent data = result.getData();
if (data != null && data.hasExtra("updated_note")) {
Note updated = data.getParcelableExtra("updated_note");
noteViewModel.updateSingleNote(updated);
scrollAfterLoadToPosition = lastScrollPosition;
}
}
- Do not call
loadNotes() after every return unless absolutely necessary (e.g., delete or category switch).
4. Restore scroll position using recyclerView.post(...), only if scrollAfterLoadToPosition >= 0.
5. Prevent unnecessary ReleaseNote updates
if (!releaseNote.equals(noteAdapter.getReleaseNote())) {
noteAdapter.setReleaseNoteHeader(releaseNote);
}
🛠 To-do list
🕓 Timing
This optimization is scheduled for a future release to allow a clean and well-tested implementation.
🧩 Affected components
MainActivity.java
NoteViewModel.java
NoteEditActivity.java
NoteAdapter.java
📝 Description
When returning from
NoteEditActivitytoMainActivity, the app currently reloads the entire note list, resulting in a noticeable jump (especially in GridView layout) and UI lag before the list becomes usable. This negatively impacts user experience, particularly with many notes or when theReleaseNoteheader is visible.🔍 Observed behavior
NoteEditActivity,noteViewModel.loadNotes()is called inMainActivity.notesLiveData, which in turn callsnoteAdapter.updateNotes(...).DiffUtil.calculateDiff(...)internally, causing the entire adapter content to be recalculated.recyclerView.scrollToPosition(...)is called to restore the previous scroll position.StaggeredGridLayoutManager, layouting is especially expensive.loadNotes()always loads the full note list, even when only one note was edited or created.ReleaseNoteheader is reset on every return, even if unchanged → triggers layout recalculation.✅ Expected behavior
updateSingleNote(...)).ViewTreeObserver.ReleaseNoteheader if its content actually changed.✅ Suggested solution (for next version)
1. Add
updateSingleNote(Note note)method inNoteViewModelnotesLiveDatalist.setValue().2. In
NoteEditActivityIntent:3. In
MainActivityActivityResultLauncher:loadNotes()after every return unless absolutely necessary (e.g., delete or category switch).4. Restore scroll position using
recyclerView.post(...), only ifscrollAfterLoadToPosition >= 0.5. Prevent unnecessary
ReleaseNoteupdates🛠 To-do list
updateSingleNote(...)method toNoteViewModelupdated_notefromNoteEditActivityusingIntent.putExtraMainActivity, avoidloadNotes()after return and use the new update method insteadnotesLiveDataobserverReleaseNoteheader if it's unchangedonReleaseNoteClosed()to avoid unnecessary reloads🕓 Timing
This optimization is scheduled for a future release to allow a clean and well-tested implementation.
🧩 Affected components
MainActivity.javaNoteViewModel.javaNoteEditActivity.javaNoteAdapter.java