0

I have a problems with a RecyclerView linked to LiveData. The RecyclerView content goes back up all the way to the top every time there is an update.

Apparently the problem lies in the way I created the adapter, as the Observer changes every time. Or so I understood. That observer is stuck inside a lambda, which is one of the many things I am still very remotely familiar with.

This is where the problem lies, apparently:

languagesViewModel.getLanguagesForUser().observe ( viewLifecycleOwner, { languages ->
        LANGUAGES_SCREEN_VIEWS.languagesRecyclerView.adapter = LanguagesRecyclerViewAdapter ( languages ) } )

I tried to get bits out of it, but it didn't work...

My first attempt was this:

var languageAdapter = LANGUAGES_SCREEN_VIEWS.languagesRecyclerView.adapter

languagesViewModel.getLanguagesForUser().observe( requireActivity(), { languages ->
            languageAdapter = LanguagesRecyclerViewAdapter(languages) } )

There was a warning that the variable is assigned but never accessed, and the list of languages is empty.

My second attempt was this:

    val languages = mutableListOf < LanguagesEntity > ()
    var languagesAdapter = LanguagesRecyclerViewAdapter(languages)

    languagesViewModel.getLanguagesForUser().observe( requireActivity(), { languages ->
        LANGUAGES_SCREEN_VIEWS.languagesRecyclerView.adapter = languagesAdapter } )

I hope it's clear that unfortunately I haven't got a clue of what I should really be doing. Not for lack of trying because I stabbed in the dark for three days before asking for help, and apparently that is the part of the code which is the problem. I do try to answer my own unanswered questions if I find a solution too. This time it just won't happen.

halfer
  • 19,824
  • 17
  • 99
  • 186
Dan
  • 530
  • 6
  • 22
  • 1
    you might wanna check https://stackoverflow.com/help/how-to-ask Your last statement before "Thank you very much in advance." is quite off. – Wale Feb 05 '21 at 02:27
  • Noted :-) It did come out of 2.00 am frustration, and a previous bizarre interaction on a related issue. – Dan Feb 05 '21 at 02:31

1 Answers1

1

you should have an internal function in adapter for setting value and notify the adapter. And also, DONT set your adapter in LiveData observer.

You should consider this architecture.

Adapter

// STEP 1 - make a function to notify the variable
internal fun setLanguage(lang: List<LanguagesEntity>) {
       languages = lang
       notifyDataSetChanged()
 }
// STEP 2 - setup recyclerview before everything
val languages = mutableListOf < LanguagesEntity > ()
var languagesAdapter = LanguagesRecyclerViewAdapter(languages)
LANGUAGES_SCREEN_VIEWS.languagesRecyclerView.adapter = languagesAdapter 


// STEP 3 - set new value to adapter
languagesViewModel.getLanguagesForUser().observe( requireActivity(), { languages ->
    
    languagesAdapter.setLanguage(language)

} )

Hope it is clear to you.

Teo
  • 876
  • 9
  • 22
  • I really can't see any difference here – Wale Feb 05 '21 at 02:15
  • You means you want 1 shot value only? – Teo Feb 05 '21 at 02:16
  • https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView.Adapter#notifyDataSetChanged() He will basically still experience the same result of data changing whenever the observer observe a change...perhaps via api call or something – Wale Feb 05 '21 at 02:20
  • 1
    notifyDataSetChanged() is too expensive when you can change the small part with changes only. – Wale Feb 05 '21 at 02:21
  • 1
    Actually you did a good job taking the Adapter Initialisation out of the Observer as expected! – Wale Feb 05 '21 at 02:23
  • Thank you. I do fully understand the solution :-) I wasn't just not familiar enough with kotlin and android yet to work it out by myself, but your answer is clear and it will help me learn more! – Dan Feb 05 '21 at 02:33
  • @Wale yes, thanks for mentioning it on expensive operation of ```notifyDataSetChanged()``` – Teo Feb 05 '21 at 03:27
  • 1
    @Dan if you want a 1 shot value return from ```LiveData```, you may consider kotlin ```Flow``` https://developer.android.com/kotlin/flow – Teo Feb 05 '21 at 03:30
  • @Teo Thank you again! I am using Flow in the DAO, yes :-) – Dan Feb 05 '21 at 07:00