# AsyncListDiffer

Artifact: [androidx.recyclerview:recyclerview](https://developer.android.com/jetpack/androidx/releases/recyclerview) [View Source](https://cs.android.com/search?q=file:androidx/recyclerview/widget/AsyncListDiffer.java+class:androidx.recyclerview.widget.AsyncListDiffer) Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/recyclerview#1.0.0)

*** ** * ** ***


```
public class AsyncListDiffer<T>
```

<br />

*** ** * ** ***

Helper for computing the difference between two lists via `https://developer.android.com/reference/androidx/recyclerview/widget/DiffUtil` on a background thread.

It can be connected to a `https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView.Adapter`, and will signal the adapter of changes between sumbitted lists.

For simplicity, the `https://developer.android.com/reference/androidx/recyclerview/widget/ListAdapter` wrapper class can often be used instead of the AsyncListDiffer directly. This AsyncListDiffer can be used for complex cases, where overriding an adapter base class to support asynchronous List diffing isn't convenient.

The AsyncListDiffer can consume the values from a LiveData of `List` and present the data simply for an adapter. It computes differences in list contents via `https://developer.android.com/reference/androidx/recyclerview/widget/DiffUtil` on a background thread as new `List`s are received.

Use `https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer#getCurrentList()` to access the current List, and present its data objects. Diff results will be dispatched to the ListUpdateCallback immediately before the current list is updated. If you're dispatching list updates directly to an Adapter, this means the Adapter can safely access list items and total size via `https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer#getCurrentList()`.

A complete usage pattern with Room would look like this:

```
@Dao
interface UserDao {
    @Query("SELECT * FROM user ORDER BY lastName ASC")
    public abstract LiveData<List<User>> usersByLastName();
}

class MyViewModel extends ViewModel {
    public final LiveData<List<User>> usersList;
    public MyViewModel(UserDao userDao) {
        usersList = userDao.usersByLastName();
    }
}

class MyActivity extends AppCompatActivity {
    @Override
    public void onCreate(Bundle savedState) {
        super.onCreate(savedState);
        MyViewModel viewModel = new ViewModelProvider(this).get(MyViewModel.class);
        RecyclerView recyclerView = findViewById(R.id.user_list);
        UserAdapter adapter = new UserAdapter();
        viewModel.usersList.observe(this, list -> adapter.submitList(list));
        recyclerView.setAdapter(adapter);
    }
}

class UserAdapter extends RecyclerView.Adapter<UserViewHolder> {
    private final AsyncListDiffer<User> mDiffer = new AsyncListDiffer(this, DIFF_CALLBACK);
    @Override
    public int getItemCount() {
        return mDiffer.getCurrentList().size();
    }
    public void submitList(List<User> list) {
        mDiffer.submitList(list);
    }
    @Override
    public void onBindViewHolder(UserViewHolder holder, int position) {
        User user = mDiffer.getCurrentList().get(position);
        holder.bindTo(user);
    }
    public static final DiffUtil.ItemCallback<User> DIFF_CALLBACK
            = new DiffUtil.ItemCallback<User>() {
        @Override
        public boolean areItemsTheSame(
                @NonNull User oldUser, @NonNull User newUser) {
            // User properties may have changed if reloaded from the DB, but ID is fixed
            return oldUser.getId() == newUser.getId();
        }
        @Override
        public boolean areContentsTheSame(
                @NonNull User oldUser, @NonNull User newUser) {
            // NOTE: if you use equals, your object must properly override Object#equals()
            // Incorrectly returning false here will result in too many animations.
            return oldUser.equals(newUser);
        }
    }
}
```

| Parameters |
|---|---|
| `<T>` | Type of the lists this AsyncListDiffer will receive. |

| See also |
|---|---|
| `https://developer.android.com/reference/androidx/recyclerview/widget/DiffUtil` |   |
| `https://developer.android.com/reference/androidx/recyclerview/widget/AdapterListUpdateCallback` |   |

## Summary

| ### Nested types |
|---|
| `public interface https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer.ListListener<T>` Listener for when the current List is updated. |

| ### Public constructors |
|---|
| `https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer#AsyncListDiffer(androidx.recyclerview.widget.RecyclerView.Adapter,androidx.recyclerview.widget.DiffUtil.ItemCallback<T>)( @https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView.Adapter adapter, @https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/recyclerview/widget/DiffUtil.ItemCallback<T> diffCallback )` Convenience for `AsyncListDiffer(new AdapterListUpdateCallback(adapter), new AsyncDifferConfig.Builder().setDiffCallback(diffCallback).build());` |
| `https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer#AsyncListDiffer(androidx.recyclerview.widget.ListUpdateCallback,androidx.recyclerview.widget.AsyncDifferConfig<T>)( @https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/recyclerview/widget/ListUpdateCallback listUpdateCallback, @https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/recyclerview/widget/AsyncDifferConfig<T> config )` Create a AsyncListDiffer with the provided config, and ListUpdateCallback to dispatch updates to. |

| ### Public methods |
|---|---|
| `void` | `https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer#addListListener(androidx.recyclerview.widget.AsyncListDiffer.ListListener<T>)(@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer.ListListener<T> listener)` Add a ListListener to receive updates when the current List changes. |
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/java/util/List.html<T>` | `https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer#getCurrentList()()` Get the current List - any diffing to present this list has already been computed and dispatched via the ListUpdateCallback. |
| `void` | `https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer#removeListListener(androidx.recyclerview.widget.AsyncListDiffer.ListListener<T>)(@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer.ListListener<T> listener)` Remove a previously registered ListListener. |
| `void` | `https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer#submitList(java.util.List<T>)(@https://developer.android.com/reference/androidx/annotation/Nullable https://developer.android.com/reference/java/util/List.html<T> newList)` Pass a new List to the AdapterHelper. |
| `void` | `https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer#submitList(java.util.List<T>,java.lang.Runnable)(@https://developer.android.com/reference/androidx/annotation/Nullable https://developer.android.com/reference/java/util/List.html<T> newList, @https://developer.android.com/reference/androidx/annotation/Nullable https://developer.android.com/reference/java/lang/Runnable.html commitCallback)` Pass a new List to the AdapterHelper. |

## Public constructors

### AsyncListDiffer

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/recyclerview#1.0.0)

```
public AsyncListDiffer(
    @NonNull RecyclerView.Adapter adapter,
    @NonNull DiffUtil.ItemCallback<T> diffCallback
)
```

Convenience for `AsyncListDiffer(new AdapterListUpdateCallback(adapter),
new AsyncDifferConfig.Builder().setDiffCallback(diffCallback).build());`

| Parameters |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView.Adapter adapter` | Adapter to dispatch position updates to. |
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/recyclerview/widget/DiffUtil.ItemCallback<T> diffCallback` | ItemCallback that compares items to dispatch appropriate animations when |

| See also |
|---|---|
| `https://developer.android.com/reference/androidx/recyclerview/widget/DiffUtil.DiffResult#dispatchUpdatesTo(androidx.recyclerview.widget.RecyclerView.Adapter)` |   |

### AsyncListDiffer

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/recyclerview#1.0.0)

```
public AsyncListDiffer(
    @NonNull ListUpdateCallback listUpdateCallback,
    @NonNull AsyncDifferConfig<T> config
)
```

Create a AsyncListDiffer with the provided config, and ListUpdateCallback to dispatch updates to.

| Parameters |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/recyclerview/widget/ListUpdateCallback listUpdateCallback` | Callback to dispatch updates to. |
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/recyclerview/widget/AsyncDifferConfig<T> config` | Config to define background work Executor, and DiffUtil.ItemCallback for computing List diffs. |

| See also |
|---|---|
| `https://developer.android.com/reference/androidx/recyclerview/widget/DiffUtil.DiffResult#dispatchUpdatesTo(androidx.recyclerview.widget.RecyclerView.Adapter)` |   |

## Public methods

### addListListener

Added in [1.1.0](https://developer.android.com/jetpack/androidx/releases/recyclerview#1.1.0)

```
public void addListListener(@NonNull AsyncListDiffer.ListListener<T> listener)
```

Add a ListListener to receive updates when the current List changes.

| Parameters |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer.ListListener<T> listener` | Listener to receive updates. |

| See also |
|---|---|
| `https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer#getCurrentList()` |   |
| `https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer#removeListListener(androidx.recyclerview.widget.AsyncListDiffer.ListListener<T>)` |   |

### getCurrentList

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/recyclerview#1.0.0)

```
public @NonNull List<T> getCurrentList()
```

Get the current List - any diffing to present this list has already been computed and dispatched via the ListUpdateCallback.

If a `null` List, or no List has been submitted, an empty list will be returned.

The returned list may not be mutated - mutations to content must be done through `https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer#submitList(java.util.List<T>)`.

| Returns |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/java/util/List.html<T>` | current List. |

### removeListListener

Added in [1.1.0](https://developer.android.com/jetpack/androidx/releases/recyclerview#1.1.0)

```
public void removeListListener(@NonNull AsyncListDiffer.ListListener<T> listener)
```

Remove a previously registered ListListener.

| Parameters |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/NonNull https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer.ListListener<T> listener` | Previously registered listener. |

| See also |
|---|---|
| `https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer#getCurrentList()` |   |
| `https://developer.android.com/reference/androidx/recyclerview/widget/AsyncListDiffer#addListListener(androidx.recyclerview.widget.AsyncListDiffer.ListListener<T>)` |   |

### submitList

Added in [1.0.0](https://developer.android.com/jetpack/androidx/releases/recyclerview#1.0.0)

```
public void submitList(@Nullable List<T> newList)
```

Pass a new List to the AdapterHelper. Adapter updates will be computed on a background thread.

If a List is already present, a diff will be computed asynchronously on a background thread. When the diff is computed, it will be applied (dispatched to the `https://developer.android.com/reference/androidx/recyclerview/widget/ListUpdateCallback`), and the new List will be swapped in.

| Parameters |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/Nullable https://developer.android.com/reference/java/util/List.html<T> newList` | The new List. |

### submitList

Added in [1.1.0](https://developer.android.com/jetpack/androidx/releases/recyclerview#1.1.0)

```
public void submitList(@Nullable List<T> newList, @Nullable Runnable commitCallback)
```

Pass a new List to the AdapterHelper. Adapter updates will be computed on a background thread.

If a List is already present, a diff will be computed asynchronously on a background thread. When the diff is computed, it will be applied (dispatched to the `https://developer.android.com/reference/androidx/recyclerview/widget/ListUpdateCallback`), and the new List will be swapped in.

The commit callback can be used to know when the List is committed, but note that it may not be executed. If List B is submitted immediately after List A, and is committed directly, the callback associated with List A will not be run.

| Parameters |
|---|---|
| `@https://developer.android.com/reference/androidx/annotation/Nullable https://developer.android.com/reference/java/util/List.html<T> newList` | The new List. |
| `@https://developer.android.com/reference/androidx/annotation/Nullable https://developer.android.com/reference/java/lang/Runnable.html commitCallback` | Optional runnable that is executed when the List is committed, if it is committed. |