android.support.v7.widget.RecyclerView.AdapterDataObserver#android.support.v7.util.ListUpdateCallback源码实例Demo

下面列出了android.support.v7.widget.RecyclerView.AdapterDataObserver#android.support.v7.util.ListUpdateCallback 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

@Test
public void shouldNotApplyPresenter1ChangesWhenNotObservedUntilGetItemCount() {
  when(mockPresenter1.getItemId(REPOSITORY_VALUE_B, 2)).thenReturn(10L);
  repositoryAdapter.unregisterAdapterDataObserver(redirectingObserver);

  repository1.accept(REPOSITORY_VALUE_B);
  runUiThreadTasksIncludingDelayedTasks();

  verify(mockPresenter1, never()).getItemCount(any());

  final int itemCount = repositoryAdapter.getItemCount();

  verify(mockPresenter1, never()).getItemCount(REPOSITORY_VALUE_A);
  verify(mockPresenter1).getItemCount(REPOSITORY_VALUE_B);
  assertThat(itemCount, is(
      PRESENTER_1_B_ITEM_COUNT + STATIC_ITEM_COUNT + PRESENTER_2_A_ITEM_COUNT));
  assertThat(repositoryAdapter.getItemId(2), is(10L + STATIC_ITEM_COUNT));
  verify(mockPresenter1, never()).getUpdates(any(), any(), any(ListUpdateCallback.class));
}
 
@Test
public void shouldNotApplyPresenter2ChangesEvenWhenObservedUntilGetItemCount() {
  when(mockPresenter2.getItemId(REPOSITORY_VALUE_B, 4)).thenReturn(100L);

  repository2.accept(REPOSITORY_VALUE_B);
  runUiThreadTasksIncludingDelayedTasks();

  verify(mockPresenter1, never()).getItemCount(any());

  final int itemCount = repositoryAdapter.getItemCount();

  verify(mockPresenter2, never()).getItemCount(REPOSITORY_VALUE_A);
  verify(mockPresenter2).getItemCount(REPOSITORY_VALUE_B);
  assertThat(itemCount, is(
      PRESENTER_1_A_ITEM_COUNT + STATIC_ITEM_COUNT + PRESENTER_2_B_ITEM_COUNT));
  assertThat(repositoryAdapter.getItemId(PRESENTER_1_A_ITEM_COUNT + STATIC_ITEM_COUNT + 4),
      is(100L + STATIC_ITEM_COUNT));
  verify(mockPresenter2, never()).getUpdates(any(), any(), any(ListUpdateCallback.class));
}
 
@Test
public void shouldApplyPresenter1ChangesWithEventsWhenObserved() {
  repositoryAdapter.getItemCount(); // usage
  when(mockPresenter1.getItemId(REPOSITORY_VALUE_B, 2)).thenReturn(10L);

  repository1.accept(REPOSITORY_VALUE_B);
  runUiThreadTasksIncludingDelayedTasks();

  assertThat(repositoryAdapter.getItemCount(), is(
      PRESENTER_1_B_ITEM_COUNT + STATIC_ITEM_COUNT + PRESENTER_2_A_ITEM_COUNT));
  assertThat(repositoryAdapter.getItemId(2), is(10L + STATIC_ITEM_COUNT));
  verify(mockPresenter1).getUpdates(eq(REPOSITORY_VALUE_A), eq(REPOSITORY_VALUE_B),
      any(ListUpdateCallback.class));
  applyPresenter1FromAToBChanges(verifyingWrapper(fineGrainedEvents));
  verifyNoMoreInteractions(fineGrainedEvents);
  verify(onChangeEvent, never()).run();
}
 
@Test
public void shouldApplyPresenter2ChangesWithEventsWhenObserved() {
  repositoryAdapter.getItemCount(); // usage
  when(mockPresenter2.getItemId(REPOSITORY_VALUE_B, 4)).thenReturn(100L);

  repository2.accept(REPOSITORY_VALUE_B);
  runUiThreadTasksIncludingDelayedTasks();

  assertThat(repositoryAdapter.getItemCount(), is(
      PRESENTER_1_A_ITEM_COUNT + STATIC_ITEM_COUNT + PRESENTER_2_B_ITEM_COUNT));
  assertThat(repositoryAdapter.getItemId(PRESENTER_1_A_ITEM_COUNT + STATIC_ITEM_COUNT + 4),
      is(100L + STATIC_ITEM_COUNT));
  verify(mockPresenter2).getUpdates(eq(REPOSITORY_VALUE_A), eq(REPOSITORY_VALUE_B),
      any(ListUpdateCallback.class));
  applyPresenter2FromAToBChanges(PRESENTER_1_A_ITEM_COUNT + STATIC_ITEM_COUNT,
      verifyingWrapper(fineGrainedEvents));
  verifyNoMoreInteractions(fineGrainedEvents);
  verify(onChangeEvent, never()).run();
}
 
@Test
public void shouldAskBothPresentersOnAdditionalObservableUpdate() {
  repository1.accept(REPOSITORY_VALUE_B);
  repository2.accept(REPOSITORY_VALUE_B);
  runUiThreadTasksIncludingDelayedTasks();
  repositoryAdapter.getItemCount(); // usage
  verify(mockPresenter1).getItemCount(REPOSITORY_VALUE_B); // consume method call
  verify(mockPresenter2).getItemCount(REPOSITORY_VALUE_B); // consume method call

  updateDispatcher.update();
  runUiThreadTasksIncludingDelayedTasks();
  repositoryAdapter.getItemCount();

  verify(mockPresenter1).getUpdates(eq(REPOSITORY_VALUE_B), eq(REPOSITORY_VALUE_B),
      any(ListUpdateCallback.class));
  verifyNoMoreInteractions(mockPresenter1); // should not have called getItemCount() again
  verify(mockPresenter2).getUpdates(eq(REPOSITORY_VALUE_B), eq(REPOSITORY_VALUE_B),
      any(ListUpdateCallback.class));
  verifyNoMoreInteractions(mockPresenter2); // should not have called getItemCount() again
  applyPresenter1RefreshBChanges(verifyingWrapper(fineGrainedEvents));
  applyPresenter2RefreshBChanges(PRESENTER_1_B_ITEM_COUNT + STATIC_ITEM_COUNT,
      verifyingWrapper(fineGrainedEvents));
  verifyNoMoreInteractions(fineGrainedEvents);
  verify(onChangeEvent, never()).run();
}
 
源代码6 项目: agera   文件: RepositoryAdapter.java
@Override
boolean getUpdates(final boolean reloadData,
    @NonNull final ListUpdateCallback listUpdateCallback) {
  final Object oldData = data;
  final Object newData = reloadData ? repository.get() : oldData;
  if (presenter.getUpdates(oldData, newData, listUpdateCallback)) {
    data = newData;
    return true;
  }
  return false;
}
 
private static void applyPresenter1FromAToBChanges(@NonNull final ListUpdateCallback callback) {
  // From count 1 to count 3:
  // [X] -> [Y, X]
  callback.onInserted(0, 1);
  // [Y, X] -> [Y, X']
  callback.onChanged(1, 1, PAYLOAD_PRESENTER_1_VALUE_A_TO_B);
  // [Y, X] -> [Y, X', Z]
  callback.onInserted(2, 1);
}
 
private static void applyPresenter1FromBToAChanges(@NonNull final ListUpdateCallback callback) {
  // From count 3 to count 1:
  // [Y, X', Z] -> [Y, Z]
  callback.onRemoved(1, 1);
  // [Y, Z] -> []
  callback.onRemoved(0, 2);
  // [] -> [X]
  callback.onInserted(0, 1);
}
 
private static void applyPresenter2FromAToBChanges(
    final int offset, @NonNull final ListUpdateCallback callback) {
  // From count 4 to count 5:
  // [M, N, O, P] -> [P, M, N, O]
  callback.onMoved(3 + offset, offset);
  // [P, M, N, O] -> [P, M]
  callback.onRemoved(2 + offset, 2);
  // [P, M] -> [P, X, Y, Z, M]
  callback.onInserted(1 + offset, 3);
}
 
private static void applyPresenter2FromBToAChanges(
    final int offset, @NonNull final ListUpdateCallback callback) {
  // From count 5 to count 4:
  // [P, X, Y, Z, M] -> [M, P, X, Y, Z]
  callback.onMoved(4 + offset, offset);
  // [M, P, X, Y, Z] -> [M, P]
  callback.onRemoved(2 + offset, 3);
  // [M, P] -> [M, N, O, P]
  callback.onInserted(1 + offset, 2);
}
 
@After
public void tearDown() {
  verify(mockStaticItemPresenter, never()).getUpdates(
      any(), any(), any(ListUpdateCallback.class));
  repositoryAdapter.stopObserving();
  if (repositoryAdapter.hasObservers()) {
    repositoryAdapter.unregisterAdapterDataObserver(redirectingObserver);
  }
}
 
@Test
public void shouldSendDataChangeEventAndDisableUpdatesUntilGetItemCount() {
  when(mockPresenter1.getUpdates(any(), any(), any(ListUpdateCallback.class))).thenReturn(false);
  repositoryAdapter.getItemCount(); // usage

  repository1.accept(REPOSITORY_VALUE_B);
  runUiThreadTasksIncludingDelayedTasks();

  verify(mockPresenter1).getUpdates(eq(REPOSITORY_VALUE_A), eq(REPOSITORY_VALUE_B),
      any(ListUpdateCallback.class));
  verifyZeroInteractions(fineGrainedEvents);
  verify(onChangeEvent).run();

  updateDispatcher.update();
  runUiThreadTasksIncludingDelayedTasks();

  verifyZeroInteractions(fineGrainedEvents);
  verifyNoMoreInteractions(onChangeEvent);

  repository2.accept(REPOSITORY_VALUE_B);
  runUiThreadTasksIncludingDelayedTasks();

  verifyZeroInteractions(fineGrainedEvents);
  verifyNoMoreInteractions(onChangeEvent);

  repositoryAdapter.getItemCount(); // usage

  repository2.accept(REPOSITORY_VALUE_A);
  runUiThreadTasksIncludingDelayedTasks();

  verifyNoMoreInteractions(onChangeEvent);
  applyPresenter2FromBToAChanges(PRESENTER_1_B_ITEM_COUNT + STATIC_ITEM_COUNT,
      verifyingWrapper(fineGrainedEvents));
  verifyNoMoreInteractions(fineGrainedEvents);
}
 
源代码13 项目: hover   文件: HoverMenu.java
void setUpdatedCallback(@Nullable ListUpdateCallback listUpdatedCallback) {
    mListUpdateCallback = listUpdatedCallback;
}
 
源代码14 项目: agera   文件: RepositoryAdapter.java
boolean getUpdates(final boolean reloadData,
    @NonNull final ListUpdateCallback listUpdateCallback) {
  return true;
}
 
源代码15 项目: agera   文件: RepositoryPresenterTest.java
@Test
public void shouldHaveDefaultGetUpdatesImplementation() throws Exception {
  final boolean returnValue = new TestRepositoryPresenter().getUpdates(
      new Object(), new Object(), mock(ListUpdateCallback.class));
  assertThat(returnValue, is(false));
}
 
private static void applyPresenter1RefreshBChanges(@NonNull final ListUpdateCallback callback) {
  // From count 3 to count 3:
  // [Y, X', Z] -> [Y', X'', Z]
  callback.onChanged(0, 2, PAYLOAD_PRESENTER_1_VALUE_B_REFRESH);
}
 
private static void applyPresenter2RefreshBChanges(
    final int offset, @NonNull final ListUpdateCallback callback) {
  // From count 5 to count 5: blanket change
  callback.onChanged(offset, 5, PAYLOAD_PRESENTER_2_VALUE_B_REFRESH);
}
 
源代码18 项目: agera   文件: RepositoryPresenter.java
/**
 * Produces a sequence of fine-grained events (addition, removal, changing and moving of
 * individual items) to the given {@code listUpdateCallback} capturing the changes of data to be
 * presented by this {@link RepositoryPresenter}, in response to an update. Implementation should
 * do either of the following:
 * <ul>
 * <li>Produce and dispatch the fine-grained events that accurately describe the changes, and then
 *     return true;
 * <li>Refuse to produce the fine-grained events by returning false. This is the base
 *     implementation.
 * </ul>
 *
 * <p>While a {@link RepositoryAdapter} is {@link RepositoryAdapter#hasObservers() in use} (for
 * example, attached to a {@code RecyclerView}), when it receives an update from a presented
 * {@link Repository}, the associated {@code RepositoryPresenter} will be asked to produce a
 * sequence of fine-grained events capturing the update; when the {@code RepositoryAdapter}
 * receives an update from one of the {@linkplain Builder#addAdditionalObservable additional
 * observables}, then all {@code RepositoryPresenter}s will be asked. If all affected
 * {@code RepositoryPresenter}s produced fine-grained events, then {@code RepositoryAdapter} will
 * apply the new data and notify the {@code RecyclerView} of the aggregated sequence of events;
 * otherwise the adapter will call {@link Adapter#notifyDataSetChanged()}, and pause all update
 * processing (both data and events) until fresh data is needed, hinted by the next call to
 * {@link RepositoryAdapter#getItemCount()}.
 *
 * <p>Notes for implementation:
 * <ul>
 * <li>If the update comes from the paired repository, then {@code oldData} is the previously
 *     presented repository value, and {@code newData} is the value newly obtained from the
 *     repository. The new value has not been applied and is not exposed through the adapter.
 *     Note that repositories are allowed to dispatch updates while maintaining
 *     {@code oldData.equals(newData)} or even {@code oldData == newData}, depending on the
 *     repository implementation.
 * <li>If the update comes from an additional observable, then it is guaranteed that
 *     {@code oldData == newData}, because the value is not reloaded from the repository.
 * <li>A {@code RepositoryPresenter} may not have a chance to produce fine-grained events in
 *     response to an update. This can happen when an earlier presenter returns false from this
 *     method, or the adapter is not {@link RepositoryAdapter#hasObservers() in use} (for example,
 *     not attached to any {@code RecyclerView}).
 * <li>{@code RepositoryAdapter} guarantees that, if this method is not called, then
 *     {@link #getItemCount} will be called before this {@code RepositoryPresenter} is asked to
 *     present any item from the new data. {@link #getItemCount} may be called again when there is
 *     a chance that the last data passed into the method may not be the latest.
 * <li>A {@code RepositoryPresenter} presenting a static item (added with {@link Builder#addItem})
 *     will not be able to produce any events for any item views presented for the static item.
 * </ul>
 *
 * @param oldData The data previously presented by this {@code RepositoryPresenter}.
 * @param newData The data to be presented by this {@code RepositoryPresenter} following the
 *     update.
 * @param listUpdateCallback A callback to record the sequence of fine-grained events to be
 *     dispatched via the {@code RepositoryAdapter} to the {@code RecyclerView}. To be used within
 *     this method call only. Positions and counts are relative to this presenter.
 * @return Whether the sequence of calls to {@code listUpdateCallback} during the execution of
 *     this method has completely and accurately described all changes.
 */
public boolean getUpdates(@NonNull final T oldData, @NonNull final T newData,
    @NonNull final ListUpdateCallback listUpdateCallback) {
  return false;
}