Update RecyclerView with Android LiveData

There are many examples of how to transfer a new list to the adapter when LiveData changes.

I am trying to update a single line (for example, the number of comments for a post) in a huge list. It would be foolish to reset the list of everything to change only one field.

I can add an observer onBindViewHolder, but I can not figure out when to remove the observer

@Override public void onBindViewHolder(ViewHolder vh, int position) { Post post = getPost(position); vh.itemView.setTag(post); post.getLiveName().observeForever(vh.nameObserver); ... } 
+7
android recycler-adapter android-livedata
source share
3 answers

Like @Lyla, you should see the whole list as LiveData in the Snippet or Activity, when receiving the changes you should install the full list of the DiffUtil adapter.

Fake Code:

 PostViewModel { LiveData<List<Post>> posts; // posts comes from DAO or Webservice } MyFragment extends LifecycleFragment { PostAdapter postAdapter; ... void onActivityCreated() { ... postViewModel.posts.observer(this, (postList) -> { postAdapter.setPosts(postList); } } } PostAdapter { void setPosts(List<Post> postList) { DiffUtil.DiffResult result = DiffUtil.calculateDiff(new DiffUtil.Callback() {...} ... } } 
+7
source share

Using DiffUtil can help with updating a single line in a huge list. You can then include LiveData in the comment list instead of a single comment or comment attribute.

Here's an example of using DiffUtil in a RecyclerView adapter and a list of LiveData observation code in a snippet .

+4
source share

Use Transformations.switchMap() to replace the underlying Post object. Then there is no need to remove and re-add observers when the cell is recycled.

 @Override public void onBindViewHolder(PostViewHolder vh, int position) { Post post = getPost(position); vh.bind(post); } 

Then in your ViewHolder class

 public class PostViewHolder extends RecyclerView.ViewHolder { private final MutableLiveData<Post> post = new MutableLiveData<>(); public PostViewHolder(View itemView) { super(itemView); LiveData<String> name = Transformations.switchMap(post, new Function<Post, LiveData<String>>() { @Override public LiveData<String> apply(Post input) { return input.getLiveName(); } }); name.observeForever(new Observer<String>() { @Override public void onChanged(@Nullable String name) { // use name } }); } public void bind(Post post) { post.setValue(post); } } 
0
source share

All Articles