Mark M. | has entered the room |
Mark M. | turned on guest access |
Jan 12 | 8:45 AM |
ani | has entered the room |
Jan 12 | 8:50 AM |
Mark M. |
hello, ani!
|
Mark M. |
how can I help you today?
|
ani |
Hey Mark, happy 2021
|
Mark M. |
Happy 2021 to you as well!
|
ani |
I have something related to Recycler view with paging, updating an item property. Wanted to pick you brain on a problem around that.
|
ani |
View paste
|
ani |
View paste
|
ani |
What is a decent way to like a user on user detail sheet on the and update the status of isLikedByMe field on the users’ list partially visible behind the detail sheet?
|
ani |
I would imagine calling notifyItemChanged(position, payload) somehow but not sure how it fits in the context of paging source and paged lists.. Additionally, I won’t necessarily have position in the users’ list on user detail screen.
|
ani |
Please let me know if the description isn't clear enough..
|
Mark M. |
If we temporarily ignore paging for the moment... the viewmodel behind your detail sheet could tell the user repository about the like/unlike action. The repository would both update your persistent data store (presumably a Web service here) and emit a fresh user object. Your fragment(?) that has the RecyclerView would get that fresh user object and update its UI accordingly (e.g., ListAdapter and DiffUtil.ItemCallback).
|
Mark M. |
paging makes this more complicated
|
Mark M. |
which version of the paging library are you using?
|
Jan 12 | 8:55 AM |
ani |
currently paging version 2
|
Mark M. |
OK. I never used that. The API is similar to Paging 1, and I never successfully used that for anything other than Room. For Kotlin developers, Paging 3 is nice, though it is only in alpha right now.
|
ani |
If I were not using paging, I could just emit a list of 1 item, because it has a unique ID, the diffutil callback would. update the appropriate user item. Did I get that right?
|
Mark M. |
no, you would emit a list of all items, with the one item updated, and DiffUtil.ItemCallback and ListAdapter would arrange to only affect the one row of your RecyclerView that was really affected
|
ani |
got ya, thanks
|
ani |
How would you deal with this in paging 3? I may be able to draw some similarities with that.
|
Jan 12 | 9:00 AM |
Mark M. |
I have not found a clean pattern for it, other than to update the data source (e.g., Web service) and tell paging to reload. A not-very-clean pattern is to get an object into the main fragment's viewmodel that represents a "local override" of a model object from paging -- when we see paging try to return that model object (e.g., via ID), we replace it with the local override.
|
Mark M. |
I wound up doing that latter approach on one project, where we wanted an "optimistic UI" -- we wanted to assume that the Web service update would succeed and just revise the UI to reflect the change (in your case, reflect the new or removed "like").
|
Mark M. |
frankly, it's a hack
|
Mark M. |
however, it was a bit of a "rush job", and we did not have time to figure out anything cleaner
|
Mark M. |
ideally, Google documents some patterns for this, as what you need (and I needed) seems reasonably commonplace
|
Jan 12 | 9:05 AM |
ani |
In the later approach, how would you be able to update the row behind the user detail sheet open. Since bind to viewholder will not be called if the item is already present on the screen..
|
ani |
thank for sharing context around that answer :)
|
Mark M. |
we are asking something to refresh -- I am trying to track down exactly what
|
Mark M. | |
Mark M. |
though, based on those docs, that may not be the best answer
|
Jan 12 | 9:10 AM |
ani |
let me take a look, thanks for the link Mark
|
ani |
View paste
|
Jan 12 | 9:15 AM |
Mark M. |
I agree that working with local data stores is easier in general, let alone with the Paging library
|
Mark M. |
and, it fits one of Google's preferred patterns, where all immediate interaction is with a local data store and the Web service simply populates that data store
|
Mark M. |
that's just not a simple architecture to implement in general and may be impractical (or against policy) for many situations
|
ani |
ya, I agree. In the case of same Entity, it breaks down like it did in my case. I can only paginate on once screen. Other screen will have to have another entity name. Since Room doesn't have dynamic table names, I cannot do room as paging source in this particular user-case.
|
Jan 12 | 9:20 AM |
ani |
View paste
|
ani |
Another hack though.
|
Mark M. |
the problem is that you should lose that object if the user scrolls the list
|
Mark M. |
and Paging will deliver you a fresh object that may or may not have your data change
|
Mark M. |
(assuming that I understand your proposal correctly)
|
Jan 12 | 9:25 AM |
Mark M. |
that was part of the reason why I put our "local override" in the viewmodel, so we could arrange to feed in our own local copy of the model object even if Paging wanted to give us something else
|
Mark M. |
that's easy to do with Paging 3 -- with Paging 2, you might need to wrap your PagedList in a decorator that could do the replacement
|
ani |
Ya, you understood it correctly. Although, it is the object delivered by paged list that I modify the property on. So scrolling or not shouldn't the same object be returned. I am thinking paged list will return the original object and not a deep copy :)
|
ani |
thanks, I ll consider the wrapping/decorator suggestion
|
Jan 12 | 9:30 AM |
Mark M. |
I am sorry that I did not have a better solution to offer you
|
Mark M. |
and... that's a wrap for today's chat
|
Mark M. |
the transcript will be posted to https://commonsware.com/office-hours/ shortly
|
Mark M. |
the next chat is Thursday at 7:30pm US Eastern
|
Mark M. |
have a pleasant day!
|
ani | has left the room |
Mark M. | turned off guest access |