room recyclerview livedata android recycler-adapter android-livedata

room - actualizar RecyclerView con Android LiveData



livedata recyclerview (3)

Hay muchos ejemplos de cómo insertar una nueva lista en el adaptador en el cambio de LiveData.

Estoy intentando actualizar una fila (p. Ej., Cantidad de comentarios para publicación) en la enorme lista. Sería una estupidez restablecer la lista completa para cambiar solo un campo.

Puedo agregar el observador enBindViewHolder, pero no puedo entender cuándo debo eliminar el observador

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


Como dijo @Lyla, debe observar la lista completa como LiveData en Fragmento o Actividad, cuando reciba cambios, debe configurar la lista completa al adaptador mediante DiffUtil.

Código falso:

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



Use Transformations.switchMap() para intercambiar el objeto Post subyacente. Entonces no hay necesidad de eliminar y volver a agregar observadores cuando la celda se recicla.

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

Luego en tu clase ViewHolder

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); } }