mirror of https://github.com/tasks/tasks
Use paging library for non-manually sorted lists
parent
ea33eed50a
commit
752f0a6661
@ -0,0 +1,19 @@
|
||||
package org.tasks.tasklist;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.DiffUtil;
|
||||
import org.tasks.data.TaskContainer;
|
||||
|
||||
public class ItemCallback extends DiffUtil.ItemCallback<TaskContainer> {
|
||||
|
||||
@Override
|
||||
public boolean areItemsTheSame(@NonNull TaskContainer oldItem, @NonNull TaskContainer newItem) {
|
||||
return oldItem.getId() == newItem.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areContentsTheSame(
|
||||
@NonNull TaskContainer oldItem, @NonNull TaskContainer newItem) {
|
||||
return oldItem.equals(newItem);
|
||||
}
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
package org.tasks.tasklist;
|
||||
|
||||
import static com.todoroo.andlib.utility.AndroidUtilities.assertMainThread;
|
||||
import static com.todoroo.andlib.utility.AndroidUtilities.assertNotMainThread;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.util.Pair;
|
||||
import androidx.recyclerview.widget.DiffUtil;
|
||||
import androidx.recyclerview.widget.DiffUtil.DiffResult;
|
||||
import androidx.recyclerview.widget.ItemTouchHelper;
|
||||
import androidx.recyclerview.widget.ListUpdateCallback;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.todoroo.astrid.activity.TaskListFragment;
|
||||
import com.todoroo.astrid.adapter.TaskAdapter;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import io.reactivex.subjects.PublishSubject;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import org.tasks.data.TaskContainer;
|
||||
|
||||
public class ManualSortRecyclerAdapter extends TaskListRecyclerAdapter {
|
||||
|
||||
private final ItemTouchHelperCallback itemTouchHelperCallback;
|
||||
private List<TaskContainer> list;
|
||||
private PublishSubject<List<TaskContainer>> publishSubject = PublishSubject.create();
|
||||
private CompositeDisposable disposables = new CompositeDisposable();
|
||||
private Queue<Pair<List<TaskContainer>, DiffResult>> updates = new LinkedList<>();
|
||||
|
||||
public ManualSortRecyclerAdapter(
|
||||
TaskAdapter adapter,
|
||||
RecyclerView recyclerView, ViewHolderFactory viewHolderFactory,
|
||||
TaskListFragment taskList,
|
||||
ActionModeProvider actionModeProvider,
|
||||
List<TaskContainer> list) {
|
||||
super(adapter, viewHolderFactory, taskList, actionModeProvider);
|
||||
this.list = list;
|
||||
itemTouchHelperCallback = new ItemTouchHelperCallback(adapter, this, this::drainQueue);
|
||||
new ItemTouchHelper(itemTouchHelperCallback).attachToRecyclerView(recyclerView);
|
||||
Pair<List<TaskContainer>, DiffResult> initial = Pair.create(list, null);
|
||||
disposables.add(
|
||||
publishSubject
|
||||
.observeOn(Schedulers.computation())
|
||||
.scan(initial, this::calculateDiff)
|
||||
.skip(1)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(this::applyDiff));
|
||||
}
|
||||
|
||||
private Pair<List<TaskContainer>, DiffResult> calculateDiff(
|
||||
Pair<List<TaskContainer>, DiffResult> last, List<TaskContainer> next) {
|
||||
assertNotMainThread();
|
||||
|
||||
DiffCallback cb = new DiffCallback(last.first, next, adapter);
|
||||
DiffResult result = DiffUtil.calculateDiff(cb, true);
|
||||
|
||||
return Pair.create(next, result);
|
||||
}
|
||||
|
||||
private void applyDiff(Pair<List<TaskContainer>, DiffResult> update) {
|
||||
assertMainThread();
|
||||
|
||||
updates.add(update);
|
||||
|
||||
if (!itemTouchHelperCallback.isDragging()) {
|
||||
drainQueue();
|
||||
}
|
||||
}
|
||||
|
||||
private void drainQueue() {
|
||||
assertMainThread();
|
||||
|
||||
Pair<List<TaskContainer>, DiffResult> update = updates.poll();
|
||||
while (update != null) {
|
||||
list = update.first;
|
||||
update.second.dispatchUpdatesTo((ListUpdateCallback) this);
|
||||
update = updates.poll();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
|
||||
disposables.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskContainer getItem(int position) {
|
||||
return list.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submitList(List<TaskContainer> list) {
|
||||
publishSubject.onNext(list);
|
||||
}
|
||||
|
||||
void moved(int from, int to, int indent) {
|
||||
adapter.moved(from, to, indent);
|
||||
TaskContainer task = list.remove(from);
|
||||
list.add(from < to ? to - 1 : to, task);
|
||||
taskList.loadTaskListContent();
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package org.tasks.tasklist;
|
||||
|
||||
import androidx.paging.AsyncPagedListDiffer;
|
||||
import androidx.paging.PagedList;
|
||||
import androidx.recyclerview.widget.AsyncDifferConfig;
|
||||
import com.todoroo.astrid.activity.TaskListFragment;
|
||||
import com.todoroo.astrid.adapter.TaskAdapter;
|
||||
import java.util.List;
|
||||
import org.tasks.data.TaskContainer;
|
||||
|
||||
public class PagedListRecyclerAdapter extends TaskListRecyclerAdapter {
|
||||
|
||||
private AsyncPagedListDiffer<TaskContainer> differ;
|
||||
|
||||
public PagedListRecyclerAdapter(
|
||||
TaskAdapter adapter,
|
||||
ViewHolderFactory viewHolderFactory,
|
||||
TaskListFragment taskList,
|
||||
ActionModeProvider actionModeProvider,
|
||||
List<TaskContainer> list) {
|
||||
super(adapter, viewHolderFactory, taskList, actionModeProvider);
|
||||
|
||||
differ =
|
||||
new AsyncPagedListDiffer<>(
|
||||
this, new AsyncDifferConfig.Builder<>(new ItemCallback()).build());
|
||||
if (list instanceof PagedList) {
|
||||
differ.submitList((PagedList<TaskContainer>) list);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return differ.getItemCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskContainer getItem(int position) {
|
||||
return differ.getItem(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submitList(List<TaskContainer> list) {
|
||||
differ.submitList((PagedList<TaskContainer>) list);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue