Skip to content
This repository has been archived by the owner on Feb 27, 2022. It is now read-only.

Commit

Permalink
Add SectionAdapterListUpdateCallback. Update example 8 with example o…
Browse files Browse the repository at this point in the history
…f usage.
  • Loading branch information
luizgrp committed Nov 21, 2019
1 parent cdf4bfa commit 7a89087
Show file tree
Hide file tree
Showing 8 changed files with 205 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import io.github.luizgrp.sectionedrecyclerviewadapter.SectionAdapterListUpdateCallback;
import io.github.luizgrp.sectionedrecyclerviewadapter.Section;
import io.github.luizgrp.sectionedrecyclerviewadapter.SectionAdapter;
import io.github.luizgrp.sectionedrecyclerviewadapter.SectionedRecyclerViewAdapter;
Expand Down Expand Up @@ -108,6 +113,21 @@ public void onHeaderClearButtonClicked(@NonNull final NameSection section) {
}
}

@Override
public void onHeaderShuffleButtonClicked(@NonNull final NameSection section) {
final SectionAdapterListUpdateCallback adapterListUpdateCallback = new SectionAdapterListUpdateCallback(sectionedAdapter.getAdapterForSection(section));
final List<Person> oldList = section.getList();
final List<Person> newList = new ArrayList<>(oldList);
Collections.shuffle(newList);

final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new PersonListDiffCallback(oldList, newList));

section.clear();
section.addAll(newList);

diffResult.dispatchUpdatesTo(adapterListUpdateCallback);
}

@Override
public void onHeaderRemoveButtonClicked(@NonNull final NameSection section) {
final int sectionItemsTotal = section.getSectionItemsTotal();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class HeaderViewHolder extends RecyclerView.ViewHolder {
final TextView tvTitle;
final Button btnAdd;
final Button btnClear;
final Button btnShuffle;
final Button btnRemove;
final Button btnStateLoaded;
final Button btnStateLoading;
Expand All @@ -25,6 +26,7 @@ class HeaderViewHolder extends RecyclerView.ViewHolder {
tvTitle = view.findViewById(R.id.tvTitle);
btnAdd = view.findViewById(R.id.btnAdd);
btnClear = view.findViewById(R.id.btnClear);
btnShuffle = view.findViewById(R.id.btnShuffle);
btnRemove = view.findViewById(R.id.btnRemove);
btnStateLoaded = view.findViewById(R.id.btnStateLoaded);
btnStateLoading = view.findViewById(R.id.btnStateLoading);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,17 @@ public void onBindHeaderViewHolder(RecyclerView.ViewHolder holder) {

headerHolder.btnClear.setOnClickListener(v -> clickListener.onHeaderClearButtonClicked(this));

headerHolder.btnShuffle.setOnClickListener(v -> clickListener.onHeaderShuffleButtonClicked(this));

headerHolder.btnRemove.setOnClickListener(view ->
clickListener.onHeaderRemoveButtonClicked(this));

headerHolder.btnStateLoaded.setOnClickListener(v -> clickListener.onHeaderLoadedButtonClicked(this));

headerHolder.btnStateLoading.setOnClickListener(v -> clickListener.onHeaderLoadingButtonClicked(this));

headerHolder.btnStateFailed.setOnClickListener(v -> clickListener.onHeaderFailedButtonClicked(this));

headerHolder.btnStateEmpty.setOnClickListener(v -> clickListener.onHeaderEmptyButtonClicked(this));
}

Expand All @@ -96,10 +101,18 @@ public RecyclerView.ViewHolder getEmptyViewHolder(final View view) {
return new EmptyViewHolder(view);
}

@NonNull List<Person> getList() {
return list;
}

void add(final int position, @NonNull final Person person) {
list.add(position, person);
}

void addAll(@NonNull final List<Person> newList) {
list.addAll(newList);
}

void remove(final int position) {
list.remove(position);
}
Expand All @@ -116,6 +129,8 @@ interface ClickListener {

void onHeaderClearButtonClicked(@NonNull final NameSection section);

void onHeaderShuffleButtonClicked(@NonNull final NameSection section);

void onHeaderRemoveButtonClicked(@NonNull final NameSection section);

void onHeaderLoadedButtonClicked(@NonNull final NameSection section);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package io.github.luizgrp.sectionedrecyclerviewadapter.demo.example8;

import java.util.List;

import androidx.recyclerview.widget.DiffUtil;

public class PersonListDiffCallback extends DiffUtil.Callback {

private final List<Person> oldList;
private final List<Person> newList;

PersonListDiffCallback(final List<Person> oldList, final List<Person> newList) {
this.oldList = oldList;
this.newList = newList;
}

@Override
public int getOldListSize() {
return oldList != null ? oldList.size() : 0;
}

@Override
public int getNewListSize() {
return newList != null ? newList.size() : 0;
}

@Override
public boolean areItemsTheSame(final int oldItemPosition, final int newItemPosition) {
return newList.get(newItemPosition).id.equals(oldList.get(oldItemPosition).id);
}

@Override
public boolean areContentsTheSame(final int oldItemPosition, final int newItemPosition) {
return newList.get(newItemPosition).equals(oldList.get(oldItemPosition));
}
}
14 changes: 14 additions & 0 deletions app/src/main/res/layout/section_ex8_header.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,20 @@
android:textColor="@color/white"
android:textStyle="bold" />

<Button
android:id="@+id/btnShuffle"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_marginStart="15dp"
android:layout_marginLeft="15dp"
android:background="@drawable/selector_btn"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="@string/shuffle"
android:textColor="@color/white"
android:textStyle="bold" />

<Button
android:id="@+id/btnRemove"
style="?android:attr/buttonBarButtonStyle"
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,12 @@
<string name="more">MORE</string>
<string name="see_more">See more..</string>
<string name="failed_load">Failed to load, tap to try again.</string>
<string name="empty_list">This list is empty.</string>
<string name="empty_list">This section is empty.</string>

<string name="add">ADD</string>
<string name="clear">CLEAR</string>
<string name="remove">REMOVE</string>
<string name="shuffle">SHUFFLE</string>
<string name="loaded">LOADED</string>
<string name="loading">LOADING</string>
<string name="failed">FAILED</string>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package io.github.luizgrp.sectionedrecyclerviewadapter;

import androidx.annotation.Nullable;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListUpdateCallback;

/**
* ListUpdateCallback that dispatches update events to the given {@link SectionAdapter}.
*
* @see DiffUtil.DiffResult#dispatchUpdatesTo(ListUpdateCallback)
*/
public class SectionAdapterListUpdateCallback implements ListUpdateCallback {

@SuppressWarnings("PMD.BeanMembersShouldSerialize")
private final SectionAdapter sectionAdapter;

public SectionAdapterListUpdateCallback(final SectionAdapter sectionAdapter) {
this.sectionAdapter = sectionAdapter;
}

@Override
public void onInserted(final int position, final int count) {
sectionAdapter.notifyItemRangeInserted(position, count);
}

@Override
public void onRemoved(final int position, final int count) {
sectionAdapter.notifyItemRangeRemoved(position, count);
}

@Override
public void onMoved(final int fromPosition, final int toPosition) {
sectionAdapter.notifyItemMoved(fromPosition, toPosition);
}

@Override
public void onChanged(final int position, final int count, @Nullable final Object payload) {
sectionAdapter.notifyItemRangeChanged(position, count, payload);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package io.github.luizgrp.sectionedrecyclerviewadapter;

import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import static org.mockito.Mockito.verify;

public class SectionAdapterListUpdateCallbackTest {

@Mock
private SectionAdapter sectionAdapter;

private SectionAdapterListUpdateCallback sectionAdapterListUpdateCallback;

@Before
public void setUp() {
MockitoAnnotations.initMocks(this);

sectionAdapterListUpdateCallback = new SectionAdapterListUpdateCallback(sectionAdapter);
}

@Test
public void givenSectionAdapter_whenOnInserted_thenNotifyItemRangeInsertedIsCalled() {
// Given
final int position = 3;
final int count = 9;

// When
sectionAdapterListUpdateCallback.onInserted(position, count);

// Then
verify(sectionAdapter).notifyItemRangeInserted(position, count);
}

@Test
public void givenSectionAdapter_whenOnRemoved_thenNotifyItemRangeRemovedIsCalled() {
// Given
final int position = 3;
final int count = 9;

// When
sectionAdapterListUpdateCallback.onRemoved(position, count);

// Then
verify(sectionAdapter).notifyItemRangeRemoved(position, count);
}

@Test
public void givenSectionAdapter_whenOnMoved_thenNotifyItemMovedIsCalled() {
// Given
final int fromPosition = 3;
final int toPosition = 9;

// When
sectionAdapterListUpdateCallback.onMoved(fromPosition, toPosition);

// Then
verify(sectionAdapter).notifyItemMoved(fromPosition, toPosition);
}

@Test
public void givenSectionAdapter_whenOnChanged_thenNotifyItemRangeChangedIsCalled() {
// Given
final int position = 3;
final int count = 9;
final Object payload = new Object();

// When
sectionAdapterListUpdateCallback.onChanged(position, count, payload);

// Then
verify(sectionAdapter).notifyItemRangeChanged(position, count, payload);
}
}

0 comments on commit 7a89087

Please # to comment.