Use DiffUtil with call log

This commit is contained in:
xynngh 2020-05-13 16:29:21 +04:00
parent 7f1ed07262
commit 2cc3a19684
2 changed files with 63 additions and 12 deletions

View File

@ -1,5 +1,6 @@
package dummydomain.yetanothercallblocker; package dummydomain.yetanothercallblocker;
import android.text.TextUtils;
import android.text.format.DateUtils; import android.text.format.DateUtils;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -9,8 +10,10 @@ 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 androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import java.util.Collections;
import java.util.List; import java.util.List;
import dummydomain.yetanothercallblocker.data.CallLogItem; import dummydomain.yetanothercallblocker.data.CallLogItem;
@ -22,12 +25,47 @@ public class CallLogItemRecyclerViewAdapter
void onListFragmentInteraction(CallLogItem item); void onListFragmentInteraction(CallLogItem item);
} }
private final List<CallLogItem> items; private static class DiffUtilCallback extends DiffUtil.Callback {
private List<CallLogItem> oldList;
private List<CallLogItem> newList;
DiffUtilCallback(List<CallLogItem> oldList, List<CallLogItem> 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) {
CallLogItem oldItem = oldList.get(oldItemPosition);
CallLogItem newItem = newList.get(newItemPosition);
return newItem.type == oldItem.type
&& TextUtils.equals(newItem.number, oldItem.number)
&& newItem.timestamp == oldItem.timestamp
&& newItem.duration == oldItem.duration;
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return false; // time always updates
}
}
private final @Nullable OnListInteractionListener listener; private final @Nullable OnListInteractionListener listener;
public CallLogItemRecyclerViewAdapter(List<CallLogItem> items, private List<CallLogItem> items = Collections.emptyList();
@Nullable OnListInteractionListener listener) {
this.items = items; public CallLogItemRecyclerViewAdapter(@Nullable OnListInteractionListener listener) {
this.listener = listener; this.listener = listener;
} }
@ -49,6 +87,15 @@ public class CallLogItemRecyclerViewAdapter
return items.size(); return items.size();
} }
public void setItems(List<CallLogItem> items) {
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(
new DiffUtilCallback(this.items, items));
this.items = items;
diffResult.dispatchUpdatesTo(this);
}
private void onClick(int index) { private void onClick(int index) {
if (index != RecyclerView.NO_POSITION && listener != null) { if (index != RecyclerView.NO_POSITION && listener != null) {
listener.onListFragmentInteraction(items.get(index)); listener.onListFragmentInteraction(items.get(index));

View File

@ -5,6 +5,7 @@ import android.content.Intent;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Parcelable;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
@ -12,13 +13,13 @@ import android.view.View;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode; import org.greenrobot.eventbus.ThreadMode;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import dummydomain.yetanothercallblocker.data.CallLogHelper; import dummydomain.yetanothercallblocker.data.CallLogHelper;
@ -38,7 +39,7 @@ public class MainActivity extends AppCompatActivity {
private final UpdateScheduler updateScheduler = UpdateScheduler.get(App.getInstance()); private final UpdateScheduler updateScheduler = UpdateScheduler.get(App.getInstance());
private CallLogItemRecyclerViewAdapter callLogAdapter; private CallLogItemRecyclerViewAdapter callLogAdapter;
private List<CallLogItem> callLogItems = new ArrayList<>(); private RecyclerView recyclerView;
private AsyncTask<Void, Void, Boolean> checkMainDbTask; private AsyncTask<Void, Void, Boolean> checkMainDbTask;
private AsyncTask<Void, Void, List<CallLogItem>> loadCallLogTask; private AsyncTask<Void, Void, List<CallLogItem>> loadCallLogTask;
@ -48,10 +49,10 @@ public class MainActivity extends AppCompatActivity {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
callLogAdapter = new CallLogItemRecyclerViewAdapter(callLogItems, this::onCallLogItemClicked); callLogAdapter = new CallLogItemRecyclerViewAdapter(this::onCallLogItemClicked);
RecyclerView recyclerView = findViewById(R.id.callLogList); recyclerView = findViewById(R.id.callLogList);
recyclerView.setAdapter(callLogAdapter); recyclerView.setAdapter(callLogAdapter);
recyclerView.addItemDecoration(new CustomVerticalDivider(this)); recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
} }
@Override @Override
@ -228,9 +229,12 @@ public class MainActivity extends AppCompatActivity {
@Override @Override
protected void onPostExecute(List<CallLogItem> items) { protected void onPostExecute(List<CallLogItem> items) {
callLogItems.clear(); // workaround for auto-scrolling to first item
callLogItems.addAll(items); // https://stackoverflow.com/a/44053550
callLogAdapter.notifyDataSetChanged(); @SuppressWarnings("ConstantConditions")
Parcelable recyclerViewState = recyclerView.getLayoutManager().onSaveInstanceState();
callLogAdapter.setItems(items);
recyclerView.getLayoutManager().onRestoreInstanceState(recyclerViewState);
setCallLogVisibility(true); setCallLogVisibility(true);
} }