Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

231
Views
RecyclerView - Stay on 0 position after notifiyItemInserted(0)

I have a chat in my application and I want my RV stay on position 0 when the new message comes and the first visible item position is 0, but new messages are added above the currently visible one, but the visible items stay in view so user has to scroll to see new message.

My adapter was extended from RecyclerView.Adapter<RecyclerView.ViewHolder> and I found a little hacky solution to get it work:

private suspend fun update(newItems: List<IChatItem>) {
    var recyclerViewState: Parcelable? = null
    if ((recyclerView?.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition() == 0) {
        recyclerViewState = recyclerView?.layoutManager?.onSaveInstanceState()
    }

    val diffResult = withContext(Dispatchers.Default) {
        DiffUtil.calculateDiff(Diff(this.currentItems, newItems))
    }

    diffResult.dispatchUpdatesTo(this)

    recyclerViewState?.let {
        recyclerView?.layoutManager?.onRestoreInstanceState(recyclerViewState)
    }
}

The thing is saving RV state and after DiffUtil completes it's work, restore it. It did work, but now I'm trying to implement new adapter and extend my adapter class from ListAdapter because it launches DiffUtil in another thread. It works good, but the problem is I can't implement my previous solution here, it just doesn't work.

I tried following:

override fun submitList(list: MutableList<IChatItem>?) {
    var recyclerViewState: Parcelable? = null
    if ((recyclerView?.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition() == 0) {
        recyclerViewState = recyclerView?.layoutManager?.onSaveInstanceState()
    }

    super.submitList(list)

    recyclerViewState?.let {
        recyclerView?.layoutManager?.onRestoreInstanceState(recyclerViewState)
    }
}

But this doesn't work anymore. Does anybody have a solution?

PS: I found this question - Inserting RecyclerView items at zero position - always stay scrolled to top, but I don't think this is the best solution to add empty invisible items in adapter's list. Any other ideas?

UPD: as I thought - because this adapter launches DiffUtil in another thread, it restored RV state before DiffUtil completes it's job. This code works:

override fun submitList(list: List<IChatItem>?) {
    var recyclerViewState: Parcelable? = null
    if ((recyclerView?.layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition() == 0) {
        recyclerViewState = recyclerView?.layoutManager?.onSaveInstanceState()
    }


    super.submitList(list)

    recyclerViewState?.let {
            Handler().postDelayed( 
                { 
                    recyclerView?.layoutManager?.onRestoreInstanceState(recyclerViewState) 
                }, 1000
            )
    }
}

But ofc this is not what I want. Is there any way to detect when DiffUtil is done with everything?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

You can use RecyclerView.AdapterDataObserver() and handle what you need.

Create your listener class that implement RecyclerView.AdapterDataObserver()

and in your adapter constructor call registerAdapterDataObserver(your listener)

and then handle your callbacks.

See RecyclerView.AdapterDataObserver

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!