Menu
Who Do Is
  • Home
  • What
  • How
  • Is
  • Can
  • Are
  • Does
  • Do
  • Why
  • Who
  • Where
  • Which
  • Which
  • Should
  • Will
  • When
  • What’s
  • Did
Who Do Is

[ANSWERED] sorting – how to properly sort a list using repository pattern and live data in an MVVM android application?

Posted on November 14, 2022

Solution 1 :

I think there is a problem in your assumption

Now lets get to the actual issue:

As long as the sorting feature is turned on, everything is fine and the user will see “list 1”, “list 2”, “list 3”, “list 4”.

But now, lets say the user turns the sorting feature off, and adds another list, “list 0”

[…]

Desired result: “list 1″,”list 2″,”list 3″,”list 4″,”list 0” (unsorted, but previous order is kept)

Actual result: “list 3″,”list 1″,”list 2″,”list 4″,”list 0” (the previous sorting of lists 1,2,3 is now lost).

As user I would expect to change the sorting behavior as soon as I turned sorting on or off. So after the user turned off sorting, the displayed order of items would be again: “list 3″,”list 1″,”list 2″,”list 4”. When then another list is added, it would be (without sorting) appended to the end, just as you wrote, but without surprising sorting change for the user.

If you really want to achieve what you describe above, I guess you will have to add a sort_index field to your table that is used as ordering criterion. You could then update that field when you sort by list title, creation date, and so on. When you then sort by this field (which you also could let room/the database do for you, which should be more efficient), the user gets a consistent behavior of the app.

More advanced could be to create an additional “mapping” table that has a column for the index of your lists and a second for the actual order (sort_index from above). Of course this list could also be held in your view model and not be a field/table in your database as it can be created on-the-fly.

Another benefit of having this field is that it would allow your user to manually sort the list via drag and drop and you would just have to update the indices accordingly.

READ  [ANSWERED] android - How to cancel slow emission when using rxjava
Powered by Inline Related Posts

Solution 2 :

here is another problem i ran into, and the solution i decided to go with (hope this will help others):

first of all, i went with the suggested method of changing the sorting order as soon as the user clicks the “sort” button. meaning instead of thinking about it in terms of “now its sorting, now its not”, i now think of it as “data is always sorted by something (even when its ‘unsorted’)”.
i wanted the “unsorted” list (default sorting) to be the same order as the items appear in the database, however my ViewModel was setup in such a way that i couldn’t get that original database items directly.

for the sake of brevity, i have something like this:

//inside view model class
val allLists : LiveData<List<UserList>> = repository.getAllLists()

so when i wanted to use the default sorting i thought of 2 options:

  1. add a function in the repository that sets the value of the getAllLists() to itself, thus triggering the observer – but that didn’t seem like a nice solution
  2. maintain another list in the ViewModel which is a copy of the one returned by the database, thus it would always be ordered the way the database retrieves it (and the “default sorting” would have the value of that list) – but thats a waste of memory and also extra complexity (not much more, but still)

what i ended up doing is adding a field created to my item which is simply set to System.currentTimeMillis() whenever an instance of my item is created and use that as my “default sorting” – very minimal code addition (not even half a line), and added no complexity at all.

Problem :

I am writing a simple to-do list style app for android and I am having problems with adding sorting functionality.

I have a screen with a RecyclerView showing all lists that belong to the user, and I would like to add a functionality which allows the user to turn sorting on or off. The problem is that I cant seem to find a way to make the list displayed to the user stay consistently sorted after another change is made.

READ  [ANSWERED] android - How to track BluetoothAdapter state changes dynamically in Jetpack Compose?
Powered by Inline Related Posts

Lets say the lists are held in a Room database.
The easiest and most consistent way to achieve what I want is to sort the data in the database itself, but this is probably not the way to go as it would be complicated to implement (if even possible).

Most likely I should sort the data locally in my view model. I figured I could do this using MediatorLiveData which will observe the database while is itself observed by the host activity. Before updating the MediatorLiveData, I would sort the list using a flag isSorting to either return the data as-is or sort it before delivering the result.

The key to my question is that I want to be able to turn this functionality on and off, while still maintaining the order of the data afterwards (when another operation is performed). Here is an example of a typical events flow:

  1. User opens the app and the database returns: “list 3”, “list 1”, “list 2”.
  2. The data is displayed to the user as-is (unsorted)
  3. The user turns on the sorting feature
  4. The view model sorts the backing list locally
  5. The observer in the activity receives the sorted list
  6. The activity now shows “list 1”, “list 2”, “list 3”
  7. The user adds a new list: “list 4”.

Before I get to the problem part, here is some code:

Repository (shortened for brevity):

class ListsRepository {
    val db = Database().getInstance();
    
    fun getAllUserLists(userId: Int): LiveData<List<UserList>>
}

Activity (shortened for brevity):

class UserListsActivity: Activity() {

    val viewModel: UserListsViewModel    
    val adapter: UserListAdapter

    fun onCreate(savedInstanceState: Bundle?) {
        viewModel.allLists.observe(this, Observer { newData ->
            adapter.setData(newData)
            adapter.notifyDataSetChanged()
        )
    }
}

Viewmodel (shortened for brevity)

class UserListsViewModel(val userId: Int, val repository: ListsRepository ): ViewModel() {

    val allLists = MediatorLiveData<List<UserList>>()
    val isSorting = false

    init {
        allLists.addSource(repository.getAllUserLists(userId)) { userLists ->
            val result = userLists
            
            if(isSorting) {
                result = result.sortedBy { it.name }
            }
        
            value = result
        }
    }

}

Now lets get to the actual issue:

READ  [ANSWERED] android - Firebase Realtime Database limits
Powered by Inline Related Posts

As long as the sorting feature is turned on, everything is fine and the user will see “list 1”, “list 2”, “list 3”, “list 4”.

But now, lets say the user turns the sorting feature off, and adds another list, “list 0”

What happens now is:

  1. The MediatorLiveData receives the update from the database as “list 3″,”list 1″,”list 2″,”list 4″,”list 0” (the original order of the database, plus the new lists)
  2. The isSorting flag is off, so it sets the value to the returned data as-is
  3. The data is displayed to the user unsorted, but the previous sorting is now lost

Desired result: “list 1″,”list 2″,”list 3″,”list 4″,”list 0” (unsorted, but previous order is kept)

Actual result: “list 3″,”list 1″,”list 2″,”list 4″,”list 0” (the previous sorting of lists 1,2,3 is now lost).

I hope I made myself clear. Is this possible to achieve without adding too much complexity? What is the “standard way” to provide sorting functionality in an android app?

Thanks

Comments

Comment posted by or_dvir

are you saying that the order of the database response is key to achieve what i want? because i only used

Comment posted by or_dvir

there was a comment here suggesting i should always sort but only until the size of the DB minus 1. that comment is deleted now, but i wanted to comment in case anybody else thought of that. this approach might work for adding items, but will not work for deleting. imagine the DB holds 3,4,1,2. user turns on sorting and gets 1,2,3,4. now user turns off sorting and deletes list 4. the database now holds 3,1,2 and the if the view model was to sort only until the last entry, the user would get 1,3,2 wheres as i want him to see 1,2,3

Comment posted by or_dvir

change the sorting behavior as soon as I turned sorting off

Recent Posts

  • How can I play with my cat without toys?
  • What is a bag pipe band called?
  • Are Honda Civics actually fast?
  • Are Yankee candles toxic?
  • How do I pair my Michael Kors smartwatch with my Android?

Recent Comments

No comments to show.

Archives

  • January 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022

Categories

  • ¿Cómo
  • ¿Cuál
  • ¿Cuántas
  • ¿Cuánto
  • ¿Que
  • ¿Quién
  • 90” and 108” so you may have to round up to the nearest size.
  • and delete any Spotify folders from it. Once this is done
  • Android
  • Are
  • At
  • Bei
  • blink
  • C'est
  • Can
  • carbs
  • Comment
  • Did
  • Do
  • Does
  • During
  • For
  • Has
  • How
  • In
  • Is
  • Ist
  • Kann
  • Können
  • nouveau
  • On
  • or 108 inches.2020-08-03
  • Où
  • owning
  • Pourquoi
  • Puis-je
  • Quand
  • Quante
  • Quel
  • Quelle
  • Quelles
  • Quels
  • Qui
  • Should
  • Sind
  • Sollte
  • spiritual
  • tap the downward-facing arrow on the top left. A downward-facing arrow will appear underneath each song in the album; they'll turn green as the download completes.2020-07-28
  • Uncategorized
  • Wann
  • Warum
  • Was
  • Welche
  • Welcher
  • Welches
  • Welke
  • Wer
  • Were
  • What
  • What's
  • When
  • Where
  • Which
  • Who
  • Whose
  • Why
  • Wie
  • Will
  • Wo
  • Woher
  • you will receive two curtains each with the same measurements of width 66"" (168cm) x drop 54""(137cm).
  • you'll see a green downward-facing arrow next to each song.2021-02-26
©2023 Who Do Is | Powered by SuperbThemes & WordPress