Use ListAdapter instead of RecyclerView.Adapter

This commit is contained in:
xynngh 2020-09-28 16:16:57 +04:00
parent 52704b4dc8
commit 91e197abf3
5 changed files with 31 additions and 103 deletions

View File

@ -238,7 +238,7 @@ public class BlacklistActivity extends AppCompatActivity {
@Override @Override
protected void onPostExecute(List<BlacklistItem> items) { protected void onPostExecute(List<BlacklistItem> items) {
blacklistAdapter.setItems(items); blacklistAdapter.submitList(items);
} }
}; };
loadBlacklistTask.execute(); loadBlacklistTask.execute();

View File

@ -16,10 +16,10 @@ import androidx.core.util.ObjectsCompat;
import androidx.recyclerview.selection.ItemDetailsLookup; import androidx.recyclerview.selection.ItemDetailsLookup;
import androidx.recyclerview.selection.ItemKeyProvider; import androidx.recyclerview.selection.ItemKeyProvider;
import androidx.recyclerview.selection.SelectionTracker; import androidx.recyclerview.selection.SelectionTracker;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import java.util.Date; import java.util.Date;
import java.util.List;
import dummydomain.yetanothercallblocker.data.db.BlacklistItem; import dummydomain.yetanothercallblocker.data.db.BlacklistItem;
@ -30,7 +30,7 @@ public class BlacklistItemRecyclerViewAdapter extends GenericRecyclerViewAdapter
public BlacklistItemRecyclerViewAdapter( public BlacklistItemRecyclerViewAdapter(
@Nullable ListInteractionListener<BlacklistItem> listener) { @Nullable ListInteractionListener<BlacklistItem> listener) {
super(listener); super(new DiffUtilCallback(), listener);
} }
public void setSelectionTracker(SelectionTracker<Long> selectionTracker) { public void setSelectionTracker(SelectionTracker<Long> selectionTracker) {
@ -42,13 +42,13 @@ public class BlacklistItemRecyclerViewAdapter extends GenericRecyclerViewAdapter
@Nullable @Nullable
@Override @Override
public Long getKey(int position) { public Long getKey(int position) {
return items.get(position).getId(); return getItem(position).getId();
} }
@Override @Override
public int getPosition(@NonNull Long key) { public int getPosition(@NonNull Long key) {
for (int i = 0; i < items.size(); i++) { for (int i = 0; i < getItemCount(); i++) {
BlacklistItem item = items.get(i); BlacklistItem item = getItem(i);
if (key.equals(item.getId())) return i; if (key.equals(item.getId())) return i;
} }
return RecyclerView.NO_POSITION; return RecyclerView.NO_POSITION;
@ -81,12 +81,6 @@ public class BlacklistItemRecyclerViewAdapter extends GenericRecyclerViewAdapter
return new BlacklistItemRecyclerViewAdapter.ViewHolder(view); return new BlacklistItemRecyclerViewAdapter.ViewHolder(view);
} }
@Override
protected DiffUtilCallback getDiffUtilCallback(
List<BlacklistItem> oldList, List<BlacklistItem> newList) {
return new DiffUtilCallback(oldList, newList);
}
class ViewHolder extends GenericRecyclerViewAdapter class ViewHolder extends GenericRecyclerViewAdapter
<BlacklistItem, BlacklistItemRecyclerViewAdapter.ViewHolder>.GenericViewHolder { <BlacklistItem, BlacklistItemRecyclerViewAdapter.ViewHolder>.GenericViewHolder {
@ -148,7 +142,7 @@ public class BlacklistItemRecyclerViewAdapter extends GenericRecyclerViewAdapter
public Long getSelectionKey() { public Long getSelectionKey() {
int position = getAdapterPosition(); int position = getAdapterPosition();
return position != RecyclerView.NO_POSITION return position != RecyclerView.NO_POSITION
? items.get(position).getId() : null; ? getItem(position).getId() : null;
} }
}; };
} }
@ -162,15 +156,11 @@ public class BlacklistItemRecyclerViewAdapter extends GenericRecyclerViewAdapter
} }
static class DiffUtilCallback static class DiffUtilCallback extends DiffUtil.ItemCallback<BlacklistItem> {
extends GenericRecyclerViewAdapter.GenericDiffUtilCallback<BlacklistItem> {
DiffUtilCallback(List<BlacklistItem> oldList, List<BlacklistItem> newList) {
super(oldList, newList);
}
@Override @Override
protected boolean areItemsTheSame(BlacklistItem oldItem, BlacklistItem newItem) { public boolean areItemsTheSame(@NonNull BlacklistItem oldItem,
@NonNull BlacklistItem newItem) {
if (oldItem.getId() != null || newItem.getId() != null) { if (oldItem.getId() != null || newItem.getId() != null) {
return ObjectsCompat.equals(oldItem.getId(), newItem.getId()); return ObjectsCompat.equals(oldItem.getId(), newItem.getId());
} }
@ -179,7 +169,8 @@ public class BlacklistItemRecyclerViewAdapter extends GenericRecyclerViewAdapter
} }
@Override @Override
protected boolean areContentsTheSame(BlacklistItem oldItem, BlacklistItem newItem) { public boolean areContentsTheSame(@NonNull BlacklistItem oldItem,
@NonNull BlacklistItem newItem) {
return ObjectsCompat.equals(oldItem.getPattern(), newItem.getPattern()) return ObjectsCompat.equals(oldItem.getPattern(), newItem.getPattern())
&& ObjectsCompat.equals(oldItem.getName(), newItem.getName()) && ObjectsCompat.equals(oldItem.getName(), newItem.getName())
&& oldItem.getNumberOfCalls() == newItem.getNumberOfCalls() && oldItem.getNumberOfCalls() == newItem.getNumberOfCalls()

View File

@ -11,6 +11,7 @@ import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView; import androidx.appcompat.widget.AppCompatImageView;
import androidx.recyclerview.widget.DiffUtil;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -23,7 +24,7 @@ public class CallLogItemRecyclerViewAdapter extends GenericRecyclerViewAdapter
<CallLogItemGroup, CallLogItemRecyclerViewAdapter.ViewHolder> { <CallLogItemGroup, CallLogItemRecyclerViewAdapter.ViewHolder> {
public CallLogItemRecyclerViewAdapter(@Nullable ListInteractionListener<CallLogItemGroup> listener) { public CallLogItemRecyclerViewAdapter(@Nullable ListInteractionListener<CallLogItemGroup> listener) {
super(listener); super(new DiffUtilCallback(), listener);
} }
@Override @Override
@ -34,12 +35,6 @@ public class CallLogItemRecyclerViewAdapter extends GenericRecyclerViewAdapter
return new ViewHolder(view); return new ViewHolder(view);
} }
@Override
protected DiffUtilCallback getDiffUtilCallback(
List<CallLogItemGroup> oldList, List<CallLogItemGroup> newList) {
return new DiffUtilCallback(oldList, newList);
}
class ViewHolder extends GenericRecyclerViewAdapter<CallLogItemGroup, ViewHolder>.GenericViewHolder { class ViewHolder extends GenericRecyclerViewAdapter<CallLogItemGroup, ViewHolder>.GenericViewHolder {
final AppCompatImageView[] callTypeIcons; final AppCompatImageView[] callTypeIcons;
@ -174,15 +169,11 @@ public class CallLogItemRecyclerViewAdapter extends GenericRecyclerViewAdapter
} }
} }
static class DiffUtilCallback static class DiffUtilCallback extends DiffUtil.ItemCallback<CallLogItemGroup> {
extends GenericRecyclerViewAdapter.GenericDiffUtilCallback<CallLogItemGroup> {
DiffUtilCallback(List<CallLogItemGroup> oldList, List<CallLogItemGroup> newList) {
super(oldList, newList);
}
@Override @Override
protected boolean areItemsTheSame(CallLogItemGroup oldGroup, CallLogItemGroup newGroup) { public boolean areItemsTheSame(@NonNull CallLogItemGroup oldGroup,
@NonNull CallLogItemGroup newGroup) {
if (oldGroup.getItems().size() != newGroup.getItems().size()) return false; if (oldGroup.getItems().size() != newGroup.getItems().size()) return false;
for (Iterator<CallLogItem> it1 = oldGroup.getItems().iterator(), for (Iterator<CallLogItem> it1 = oldGroup.getItems().iterator(),
@ -201,7 +192,8 @@ public class CallLogItemRecyclerViewAdapter extends GenericRecyclerViewAdapter
} }
@Override @Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) { public boolean areContentsTheSame(@NonNull CallLogItemGroup oldItem,
@NonNull CallLogItemGroup newItem) {
return false; // time always updates return false; // time always updates
} }

View File

@ -5,95 +5,40 @@ import android.view.View;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.ListAdapter;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import java.util.Collections;
import java.util.List;
public abstract class GenericRecyclerViewAdapter<T, V extends GenericRecyclerViewAdapter<T, V>.GenericViewHolder> public abstract class GenericRecyclerViewAdapter<T, V extends GenericRecyclerViewAdapter<T, V>.GenericViewHolder>
extends RecyclerView.Adapter<V> { extends ListAdapter<T, V> {
public interface ListInteractionListener<T> { public interface ListInteractionListener<T> {
void onListItemClicked(T item); void onListItemClicked(T item);
} }
protected @Nullable protected @Nullable ListInteractionListener<T> listener;
ListInteractionListener<T> listener;
protected List<T> items = Collections.emptyList(); public GenericRecyclerViewAdapter(DiffUtil.ItemCallback<T> itemCallback,
@Nullable ListInteractionListener<T> listener) {
public GenericRecyclerViewAdapter(@Nullable ListInteractionListener<T> listener) { super(itemCallback);
this.listener = listener; this.listener = listener;
} }
@Override @Override
public void onBindViewHolder(@NonNull V holder, int position) { public void onBindViewHolder(@NonNull V holder, int position) {
onBindViewHolder(holder, items.get(position)); onBindViewHolder(holder, getItem(position));
} }
protected void onBindViewHolder(@NonNull V holder, T item) { protected void onBindViewHolder(@NonNull V holder, T item) {
holder.bind(item); holder.bind(item);
} }
@Override
public int getItemCount() {
return items.size();
}
public void setItems(List<T> items) {
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(
getDiffUtilCallback(this.items, items));
this.items = items;
diffResult.dispatchUpdatesTo(this);
}
protected abstract GenericDiffUtilCallback<T> getDiffUtilCallback(
List<T> oldList, List<T> newList);
protected void onClick(int index) { protected void onClick(int index) {
if (index != RecyclerView.NO_POSITION && listener != null) { if (index != RecyclerView.NO_POSITION && listener != null) {
listener.onListItemClicked(items.get(index)); T item = getItem(index);
if (item != null) {
listener.onListItemClicked(item);
} }
} }
protected static class GenericDiffUtilCallback<T> extends DiffUtil.Callback {
protected List<T> oldList;
protected List<T> newList;
protected GenericDiffUtilCallback(List<T> oldList, List<T> newList) {
this.oldList = oldList;
this.newList = newList;
}
@Override
public int getOldListSize() {
return oldList.size();
}
@Override
public int getNewListSize() {
return newList.size();
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return areItemsTheSame(oldList.get(oldItemPosition), newList.get(newItemPosition));
}
protected boolean areItemsTheSame(T oldItem, T newItem) {
return false;
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return areContentsTheSame(oldList.get(oldItemPosition), newList.get(newItemPosition));
}
protected boolean areContentsTheSame(T oldItem, T newItem) {
return false;
}
} }
protected abstract class GenericViewHolder extends RecyclerView.ViewHolder { protected abstract class GenericViewHolder extends RecyclerView.ViewHolder {

View File

@ -257,7 +257,7 @@ public class MainActivity extends AppCompatActivity {
// https://stackoverflow.com/a/44053550 // https://stackoverflow.com/a/44053550
@SuppressWarnings("ConstantConditions") @SuppressWarnings("ConstantConditions")
Parcelable recyclerViewState = recyclerView.getLayoutManager().onSaveInstanceState(); Parcelable recyclerViewState = recyclerView.getLayoutManager().onSaveInstanceState();
callLogAdapter.setItems(items); callLogAdapter.submitList(items);
recyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState); recyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);
setCallLogVisibility(true); setCallLogVisibility(true);