mirror of https://github.com/tasks/tasks
Add ItemTouchHelperCallback and ActionModeProvider
parent
4699e29bb8
commit
c96e518885
@ -0,0 +1,132 @@
|
||||
package org.tasks.tasklist;
|
||||
|
||||
import static org.tasks.activities.RemoteListSupportPicker.newRemoteListSupportPicker;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.view.ActionMode;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import com.todoroo.astrid.activity.TaskListActivity;
|
||||
import com.todoroo.astrid.activity.TaskListFragment;
|
||||
import com.todoroo.astrid.adapter.TaskAdapter;
|
||||
import com.todoroo.astrid.data.Task;
|
||||
import com.todoroo.astrid.service.TaskDeleter;
|
||||
import com.todoroo.astrid.service.TaskDuplicator;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import org.tasks.R;
|
||||
import org.tasks.analytics.Tracker;
|
||||
import org.tasks.analytics.Tracking;
|
||||
import org.tasks.dialogs.DialogBuilder;
|
||||
import org.tasks.injection.ForActivity;
|
||||
import org.tasks.ui.MenuColorizer;
|
||||
|
||||
public class ActionModeProvider {
|
||||
|
||||
private static final String FRAG_TAG_REMOTE_LIST_PICKER = "frag_tag_remote_list_picker";
|
||||
|
||||
private final Context context;
|
||||
private final DialogBuilder dialogBuilder;
|
||||
private final TaskDeleter taskDeleter;
|
||||
private final TaskDuplicator taskDuplicator;
|
||||
private final Tracker tracker;
|
||||
|
||||
@Inject
|
||||
public ActionModeProvider(
|
||||
@ForActivity Context context,
|
||||
DialogBuilder dialogBuilder,
|
||||
TaskDeleter taskDeleter,
|
||||
TaskDuplicator taskDuplicator,
|
||||
Tracker tracker) {
|
||||
this.context = context;
|
||||
this.dialogBuilder = dialogBuilder;
|
||||
this.taskDeleter = taskDeleter;
|
||||
this.taskDuplicator = taskDuplicator;
|
||||
this.tracker = tracker;
|
||||
}
|
||||
|
||||
public ActionMode startActionMode(
|
||||
TaskAdapter adapter,
|
||||
TaskListFragment taskList,
|
||||
TaskListRecyclerAdapter taskListRecyclerAdapter) {
|
||||
return ((TaskListActivity) context)
|
||||
.startSupportActionMode(
|
||||
new ActionMode.Callback() {
|
||||
@Override
|
||||
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
|
||||
MenuInflater inflater = actionMode.getMenuInflater();
|
||||
inflater.inflate(R.menu.menu_multi_select, menu);
|
||||
MenuColorizer.colorMenu(context, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.move_tasks:
|
||||
newRemoteListSupportPicker(null, taskList, TaskListFragment.REQUEST_MOVE_TASKS)
|
||||
.show(taskList.getFragmentManager(), FRAG_TAG_REMOTE_LIST_PICKER);
|
||||
return true;
|
||||
case R.id.delete:
|
||||
dialogBuilder
|
||||
.newMessageDialog(R.string.delete_selected_tasks)
|
||||
.setPositiveButton(
|
||||
android.R.string.ok, (dialogInterface, i) -> deleteSelectedItems())
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show();
|
||||
return true;
|
||||
case R.id.copy_tasks:
|
||||
dialogBuilder
|
||||
.newMessageDialog(R.string.copy_selected_tasks)
|
||||
.setPositiveButton(
|
||||
android.R.string.ok, ((dialogInterface, i) -> copySelectedItems()))
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyActionMode(ActionMode actionMode) {
|
||||
adapter.clearSelections();
|
||||
taskListRecyclerAdapter.onDestroyActionMode();
|
||||
}
|
||||
|
||||
private void deleteSelectedItems() {
|
||||
tracker.reportEvent(Tracking.Events.MULTISELECT_DELETE);
|
||||
List<Long> tasks = adapter.getSelected();
|
||||
taskListRecyclerAdapter.finishActionMode();
|
||||
List<Task> result = taskDeleter.markDeleted(tasks);
|
||||
taskList.onTaskDelete(result);
|
||||
taskList
|
||||
.makeSnackbar(
|
||||
context.getString(
|
||||
R.string.delete_multiple_tasks_confirmation,
|
||||
Integer.toString(result.size())))
|
||||
.show();
|
||||
}
|
||||
|
||||
private void copySelectedItems() {
|
||||
tracker.reportEvent(Tracking.Events.MULTISELECT_CLONE);
|
||||
List<Long> tasks = adapter.getSelected();
|
||||
taskListRecyclerAdapter.finishActionMode();
|
||||
List<Task> duplicates = taskDuplicator.duplicate(tasks);
|
||||
taskList.onTaskCreated(duplicates);
|
||||
taskList
|
||||
.makeSnackbar(
|
||||
context.getString(
|
||||
R.string.copy_multiple_tasks_confirmation,
|
||||
Integer.toString(duplicates.size())))
|
||||
.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,127 @@
|
||||
package org.tasks.tasklist;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.helper.ItemTouchHelper;
|
||||
import com.todoroo.astrid.activity.TaskListFragment;
|
||||
import com.todoroo.astrid.adapter.TaskAdapter;
|
||||
import com.todoroo.astrid.utility.Flags;
|
||||
|
||||
public class ItemTouchHelperCallback extends ItemTouchHelper.Callback {
|
||||
private final TaskAdapter adapter;
|
||||
private final TaskListRecyclerAdapter recyclerAdapter;
|
||||
private final TaskListFragment taskList;
|
||||
private int from = -1;
|
||||
private int to = -1;
|
||||
private boolean dragging;
|
||||
|
||||
ItemTouchHelperCallback(
|
||||
TaskAdapter adapter, TaskListRecyclerAdapter recyclerAdapter, TaskListFragment taskList) {
|
||||
this.adapter = adapter;
|
||||
this.recyclerAdapter = recyclerAdapter;
|
||||
this.taskList = taskList;
|
||||
}
|
||||
|
||||
public boolean isDragging() {
|
||||
return dragging;
|
||||
}
|
||||
|
||||
public void setDragging(boolean dragging) {
|
||||
this.dragging = dragging;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
|
||||
super.onSelectedChanged(viewHolder, actionState);
|
||||
if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {
|
||||
((ViewHolder) viewHolder).setMoving(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
|
||||
if (!adapter.isManuallySorted()) {
|
||||
return makeMovementFlags(0, 0);
|
||||
}
|
||||
ViewHolder vh = (ViewHolder) viewHolder;
|
||||
if (!recyclerAdapter.isActionModeActive()) {
|
||||
int indentFlags = 0;
|
||||
if (vh.isIndented()) {
|
||||
indentFlags |= ItemTouchHelper.LEFT;
|
||||
}
|
||||
int position = vh.getAdapterPosition();
|
||||
if (position > 0 && adapter.canIndent(position, vh.task)) {
|
||||
indentFlags |= ItemTouchHelper.RIGHT;
|
||||
}
|
||||
return makeMovementFlags(0, indentFlags);
|
||||
}
|
||||
if (dragging) {
|
||||
return makeMovementFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN, 0);
|
||||
}
|
||||
return makeMovementFlags(0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMove(
|
||||
RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
|
||||
recyclerAdapter.finishActionMode();
|
||||
int fromPosition = source.getAdapterPosition();
|
||||
int toPosition = target.getAdapterPosition();
|
||||
if (from == -1) {
|
||||
((ViewHolder) source).setSelected(false);
|
||||
from = fromPosition;
|
||||
}
|
||||
to = toPosition;
|
||||
recyclerAdapter.notifyItemMoved(fromPosition, toPosition);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getSwipeThreshold(RecyclerView.ViewHolder viewHolder) {
|
||||
return .2f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChildDraw(
|
||||
Canvas c,
|
||||
RecyclerView recyclerView,
|
||||
RecyclerView.ViewHolder viewHolder,
|
||||
float dX,
|
||||
float dY,
|
||||
int actionState,
|
||||
boolean isCurrentlyActive) {
|
||||
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
|
||||
float shiftSize = ((ViewHolder) viewHolder).getShiftSize();
|
||||
dX = Math.max(-shiftSize, Math.min(shiftSize, dX));
|
||||
}
|
||||
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
|
||||
super.clearView(recyclerView, viewHolder);
|
||||
ViewHolder vh = (ViewHolder) viewHolder;
|
||||
if (dragging) {
|
||||
vh.setMoving(false);
|
||||
dragging = false;
|
||||
if (from != -1) {
|
||||
if (from >= 0 && from != to) {
|
||||
if (from < to) {
|
||||
to++;
|
||||
}
|
||||
adapter.moved(from, to);
|
||||
taskList.loadTaskListContent(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
from = -1;
|
||||
to = -1;
|
||||
Flags.checkAndClear(Flags.TLFP_NO_INTERCEPT_TOUCH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
|
||||
adapter.indented(viewHolder.getAdapterPosition(), direction == ItemTouchHelper.RIGHT ? 1 : -1);
|
||||
taskList.loadTaskListContent(false);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue