2017-06-11 25 views
7

Es gibt viele Beispiele, wie neue Liste zu Adapter auf LiveData-Änderung zu schieben.Update RecyclerView mit Android LiveData

Ich versuche, eine Zeile (z. B. Anzahl der Kommentare für den Beitrag) in der riesigen Liste zu aktualisieren. Es wäre dumm, ganze Liste zurückzusetzen, um nur ein Feld zu ändern.

Ich bin in der Lage Beobachter onBindViewHolder hinzufügen, aber ich kann nicht verstehen, wann sollte ich Beobachter entfernen

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

Antwort

4

DiffUtil verwenden, kann mit der Aktualisierung einer Zeile in einer riesigen Liste helfen. Sie können LiveData dann die Liste der Kommentare anstelle eines einzelnen Kommentars oder Attributs eines Kommentars umbrechen lassen.

Hier ist ein Beispiel für die Verwendung von DiffUtil in einem RecyclerView adapter und list LiveData observation code in the fragment.

+1

Hallo Lyla, Ihren Link auf die "Liste Livedata Observaion Code in dem Fragment" nicht funktioniert. Es fehlt das "/ ui /" in der URL. Die richtige URL lautet [ProductListFragment.java # L75] (https://github.com/googlesamples/android-architecture-components/blob/master/BasicSample/app/src/main/java/com/example/android/persistence/ ui/ProductListFragment.java # L75) - Luke – lukegjpotter

+0

Der Link wurde repariert! Vielen Dank! – Lyla

6

Wie @Lyla sagte, sollten Sie die gesamte Liste als LiveData in Fragment oder Aktivität beobachten, wenn Änderungen erhalten, sollten Sie die gesamte Liste auf den Adapter von DiffUtil setzen.

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

Verwenden Transformations.switchMap() das darunter liegende Post Objekt zu tauschen. Dann müssen Beobachter nicht entfernt und erneut hinzugefügt werden, wenn die Zelle recycelt wird.

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

Dann in Ihrem ViewHolder Klasse

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