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() {...}
...
}
}
Usar DiffUtil puede ayudar a actualizar una fila en una lista enorme. Luego, puede hacer que LiveData ajuste la lista de comentarios en lugar de un solo comentario o atributo de un comentario.
Este es un ejemplo del uso de DiffUtil dentro de un adaptador RecyclerView y la lista del código de observación LiveData en el fragmento .
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);
}
}