How to prevent double items but also prevent entire list from refreshing?

15
January 11, 2019, at 6:10 PM

I am getting a JSON Array of user ids strings from a database:

["uid1", "uid103", "uid322"]

I am fetching this array on a time triggered loop, and I use notifyDataSetChanged with myDataSet.clear() to display the list, and to prevent duplicates. The problem with this method is that the list is constantly "refreshing", and I just want to either add or remove the items that's needed to be removed or added.

If I remove the clear() part, then the list won't refresh, but I will get duplicate items.

This is how the code (+pseudo) looks like:

trigger(just a time based loop) {  
    myDataset.clear();
    jsonArray = //the id array from the database;
    for (int i=0;i<jsonArray.length;i++){                                                                                        
        myDataset.add(new User(jsonArray.get(i), imageUrl));                                                 
        mAdapter.notifyDataSetChanged();
    }
}
Answer 1

You can use for this purpose DiffUtil class (Medium example).

It calculates differences between new and old datasets and updates it.

But if you don't want to deep dive into DiffUtil you can try to use combination of notifyItemInserted() and notifyItemChanged()

Answer 2

You need to compare the 2 lists before refreshing. So,

  • If an item is removed, Your list's size will be smaller.
  • If an item is added, the list's size will be bigger and the new item will be the last item in the retrieved array.
  • But if an item is removed and at the same time an item is added, your list's size will be the same but the last item will change.
    So, you need to check both array size and the last item before refreshing like this:

    trigger(just a time based loop) {  
        if((myDataset.size() != jsonArray.size()) || myDataset[last] != jsonArray[last]) {
                myDataset.clear();
                jsonArray = //the id array from the database;
                for (int i=0;i<jsonArray.length;i++){                                                                                        
                    myDataset.add(new User(jsonArray.get(i)));                                                 
                    mAdapter.notifyDataSetChanged();
                }
            }
        }
    
Answer 3

Change your code as below, Your loop will do all the changes in your data and once the loop is over you notify those changes to your list in one go, instead of refreshing it each time.

for (int i=0;i<jsonArray.length;i++){                                                                                        
    myDataset.add(new User(jsonArray.get(i)));                                                 
}
mAdapter.notifyDataSetChanged();

If you want to avoid duplicates use Set, add items to set from your json array and use it as datasource for your list.

READ ALSO
My app cannot see a library within a library

My app cannot see a library within a library

I created 2 Android librariesNames are LibA and LibB

48
How to make that the snackbar action button be shown in a different line if the text is long?

How to make that the snackbar action button be shown in a different line if the text is long?

I am working with the Material Design components in the support library version 280

43
Location service giving beep sound every second above android 8.0 version

Location service giving beep sound every second above android 8.0 version

I am running the background service in that iam using location service to get the current locationFor every second it gives a beep sound in above android 8

16