update RecyclerView with Android LiveData

匿名 (未验证) 提交于 2019-12-03 02:48:02

问题:

There are many examples how to push new list to adapter on LiveData change.

I'm trying to update one row (e.g number of comments for post) in the huge list. It would be stupid to reset whole list to change only one field.

I am able to add observer onBindViewHolder, but I can't understand when should I remove observer

@Override public void onBindViewHolder(ViewHolder vh, int position) {     Post post = getPost(position);     vh.itemView.setTag(post);     post.getLiveName().observeForever(vh.nameObserver);     ...  } 

回答1:

Like @Lyla said, you should observe the whole list as LiveData in Fragment or Activity, when receive changes, you should set the whole list to the adapter by DiffUtil.

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() {...}         ...     } } 


回答2:

Using DiffUtil might help with updating one row in a huge list. You can then have LiveData wrap the list of comments instead of a single comment or attribute of a comment.

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



回答3:

Use Transformations.switchMap() to swap 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);     } } 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!