cn.studyjams.s2.sj0132.bowenyan.mygirlfriend.nononsenseapps.notepad.ui.list.TaskListFragment.java Source code

Java tutorial

Introduction

Here is the source code for cn.studyjams.s2.sj0132.bowenyan.mygirlfriend.nononsenseapps.notepad.ui.list.TaskListFragment.java

Source

/*
 * Copyright (c) 2015 Jonas Kalderstam.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package cn.studyjams.s2.sj0132.bowenyan.mygirlfriend.nononsenseapps.notepad.ui.list;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.view.ActionMode;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

import java.security.InvalidParameterException;
import java.util.Collection;
import java.util.Set;
import java.util.TreeSet;

import cn.studyjams.s2.sj0132.bowenyan.mygirlfriend.R;
import cn.studyjams.s2.sj0132.bowenyan.mygirlfriend.nononsenseapps.notepad.data.model.sql.DAO;
import cn.studyjams.s2.sj0132.bowenyan.mygirlfriend.nononsenseapps.notepad.data.model.sql.Task;
import cn.studyjams.s2.sj0132.bowenyan.mygirlfriend.nononsenseapps.notepad.data.model.sql.TaskList;
import cn.studyjams.s2.sj0132.bowenyan.mygirlfriend.nononsenseapps.notepad.data.receiver.SyncStatusMonitor;
import cn.studyjams.s2.sj0132.bowenyan.mygirlfriend.nononsenseapps.notepad.data.service.gtasks.SyncHelper;
import cn.studyjams.s2.sj0132.bowenyan.mygirlfriend.nononsenseapps.notepad.ui.common.DialogDeleteCompletedTasks;
import cn.studyjams.s2.sj0132.bowenyan.mygirlfriend.nononsenseapps.notepad.ui.common.DialogMoveToList;
import cn.studyjams.s2.sj0132.bowenyan.mygirlfriend.nononsenseapps.notepad.ui.common.DialogPassword;
import cn.studyjams.s2.sj0132.bowenyan.mygirlfriend.nononsenseapps.notepad.ui.common.DialogPassword.PasswordConfirmedListener;
import cn.studyjams.s2.sj0132.bowenyan.mygirlfriend.nononsenseapps.notepad.ui.common.MenuStateController;
import cn.studyjams.s2.sj0132.bowenyan.mygirlfriend.nononsenseapps.notepad.util.ArrayHelper;
import cn.studyjams.s2.sj0132.bowenyan.mygirlfriend.nononsenseapps.notepad.util.AsyncTaskHelper;
import cn.studyjams.s2.sj0132.bowenyan.mygirlfriend.nononsenseapps.notepad.util.SharedPreferencesHelper;

public class TaskListFragment extends Fragment implements OnSharedPreferenceChangeListener,
        SyncStatusMonitor.OnSyncStartStopListener, ActionMode.Callback {

    // Must be less than -1
    public static final String LIST_ALL_ID_PREF_KEY = "show_all_tasks_choice_id";
    public static final int LIST_ID_ALL = -2;
    public static final int LIST_ID_OVERDUE = -3;
    public static final int LIST_ID_TODAY = -4;
    public static final int LIST_ID_WEEK = -5;

    public static final String LIST_ID = "list_id";
    public static final int LOADER_TASKS = 1;
    public static final int LOADER_CURRENT_LIST = 0;
    private static final String TAG = "TaskListFragment";

    RecyclerView listView;

    SimpleSectionsAdapter mAdapter;

    SyncStatusMonitor syncStatusReceiver = null;

    private long mListId = -1;

    private TaskListFragment.TaskListCallbacks mListener;

    private String mSortType = null;
    private int mRowCount = 3;

    private LoaderCallbacks<Cursor> mCallback = null;

    private ActionMode mMode;
    private SwipeRefreshLayout mSwipeRefreshLayout;
    private ItemTouchHelper touchHelper;
    private SelectedItemHandler selectedItemHandler;

    public TaskListFragment() {
        super();
    }

    public static TaskListFragment getInstance(final long listId) {
        TaskListFragment f = new TaskListFragment();
        Bundle args = new Bundle();
        args.putLong(LIST_ID, listId);
        f.setArguments(args);
        return f;
    }

    public static String whereOverDue() {
        return Task.Columns.DUE + " BETWEEN " + Task.OVERDUE + " AND " + Task.TODAY_START;
    }

    public static String andWhereOverdue() {
        return " AND " + whereOverDue();
    }

    public static String whereToday() {
        return Task.Columns.DUE + " BETWEEN " + Task.TODAY_START + " AND " + Task.TODAY_PLUS(1);
    }

    public static String andWhereToday() {
        return " AND " + whereToday();
    }

    public static String whereWeek() {
        return Task.Columns.DUE + " BETWEEN " + Task.TODAY_START + " AND (" + Task.TODAY_PLUS(5) + " -1)";
    }

    public static String andWhereWeek() {
        return " AND " + whereWeek();
    }

    void loadList() {
        listView.setLayoutManager(new LinearLayoutManager(getActivity()));
        listView.setHasFixedSize(true);
        // TODO separators
        touchHelper = new ItemTouchHelper(new DragHandler());
        listView.setAdapter(mAdapter);
        touchHelper.attachToRecyclerView(listView);

        // TODO jonas
        /*listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
          final HashMap<Long, Task> tasks = new HashMap<Long, Task>();
          // ActionMode mMode;
            
          @Override
          public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            // Must setup the contextual action menu
            final MenuInflater inflater = getActivity().getMenuInflater();
            inflater.inflate(R.menu.fragment_tasklist_context, menu);
            
            // Must clear for reuse
            tasks.clear();
            
            // For password
            mMode = mode;
            
            return true;
          }
            
          @Override
          public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            // Here you can perform updates to the CAB due to
            // an invalidate() request
            return false;
          }
            
          @Override
          public boolean onActionItemClicked(final ActionMode mode, MenuItem item) {
            // Respond to clicks on the actions in the CAB
            boolean finish = false;
            int itemId = item.getItemId();
            if (itemId == R.id.menu_delete) {
              deleteTasks(tasks);
              finish = true;
            
            } else if (itemId == R.id.menu_switch_list) {
              // show move to list dialog
              DialogMoveToList.getInstance(tasks.keySet().toArray(new Long[tasks.size()]))
          .show(getFragmentManager(), "move_to_list_dialog");
              finish = true;
            } else if (itemId == R.id.menu_share) {
              startActivity(getShareIntent());
              finish = true;
            } else {
              finish = false;
            }
            
            if (finish) {
              mode.finish(); // Action picked, so close the CAB
            }
            return finish;
          }
            
          @Override
          public void onDestroyActionMode(ActionMode mode) {
            // Here you can make any necessary updates to the activity when
            // the CAB is removed. By default, selected items are
            // deselected/unchecked.
            tasks.clear();
          }
            
          @Override
          public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
                                        boolean checked) {
            if (checked) {
              tasks.put(id, new Task(mAdapter.getCursor(position)));
            } else {
              tasks.remove(id);
            }
            // Display in action bar total number of selected items
            mode.setTitle(Integer.toString(tasks.size()));
          }
            
          String getShareText() {
            final StringBuilder sb = new StringBuilder();
            final boolean locked = SharedPreferencesHelper.isPasswordSet(getActivity());
            for (Task t : tasks.values()) {
              if (sb.length() > 0) {
        sb.append("\n\n");
              }
              if (locked) {
        sb.append(t.title);
              } else {
        sb.append(t.getText());
              }
            }
            return sb.toString();
          }
            
          String getShareSubject() {
            String result = "";
            for (Task t : tasks.values()) {
              result += ", " + t.title;
            }
            return result.length() > 0 ? result.substring(2) : result;
          }
            
          Intent getShareIntent() {
            final Intent shareIntent = new Intent(Intent.ACTION_SEND);
            shareIntent.setType("text/plain");
            shareIntent.putExtra(Intent.EXTRA_TEXT, getShareText());
            shareIntent.putExtra(Intent.EXTRA_SUBJECT, getShareSubject());
            shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
            return shareIntent;
          }
        });*/
    }

    /**
     * Delete tasks and display a snackbar with an undo action
     *
     */
    private void deleteTasks(final Set<Long> orgItemIds) {
        // If any are locked, ask for password first
        final boolean locked = SharedPreferencesHelper.isPasswordSet(getActivity());

        // copy to avoid threading issues
        final Set<Long> itemIds = new TreeSet<>();
        itemIds.addAll(orgItemIds);

        final PasswordConfirmedListener pListener = new PasswordConfirmedListener() {
            @Override
            public void onPasswordConfirmed() {
                AsyncTaskHelper.background(new AsyncTaskHelper.Job() {
                    @Override
                    public void doInBackground() {
                        for (Long id : itemIds) {
                            try {
                                Task.delete(id, getActivity());
                            } catch (Exception ignored) {
                                Log.e(TAG, "doInBackground:" + ignored.getMessage());
                            }
                        }
                    }
                });
            }
        };

        if (locked) {
            DialogPassword delpf = new DialogPassword();
            delpf.setListener(pListener);
            delpf.show(getFragmentManager(), "multi_delete_verify");
        } else {
            // Just run it directly
            Log.d(TAG, "deleteTasks: run it");
            pListener.onPasswordConfirmed();
        }
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        try {
            mListener = (TaskListFragment.TaskListCallbacks) getActivity();
        } catch (ClassCastException e) {
            throw new ClassCastException("Activity must implement " + "OnFragmentInteractionListener");
        }

        // We want to be notified of future changes to auto refresh
        PreferenceManager.getDefaultSharedPreferences(context).registerOnSharedPreferenceChangeListener(this);
    }

    void setupSwipeToRefresh() {
        // Set the offset so it comes out of the correct place
        final int toolbarHeight = getResources().getDimensionPixelOffset(R.dimen.toolbar_height);
        mSwipeRefreshLayout.setProgressViewOffset(false, -toolbarHeight, Math.round(0.7f * toolbarHeight));

        // The arrow will cycle between these colors (in order)
        mSwipeRefreshLayout.setColorSchemeResources(R.color.refresh_progress_1, R.color.refresh_progress_2,
                R.color.refresh_progress_3);

        mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                boolean syncing = SyncHelper.onManualSyncRequest(getActivity());

                if (!syncing) {
                    // Do not show refresh view
                    mSwipeRefreshLayout.setRefreshing(false);
                }
            }
        });
    }

    @Override
    public void onCreate(Bundle savedState) {
        super.onCreate(savedState);

        setHasOptionsMenu(true);

        selectedItemHandler = new SelectedItemHandler((AppCompatActivity) getActivity(), this);

        syncStatusReceiver = new SyncStatusMonitor();

        if (getArguments().getLong(LIST_ID, -1) == -1) {
            throw new InvalidParameterException("Must designate a list to open!");
        }
        mListId = getArguments().getLong(LIST_ID, -1);

        // Start loading data
        mAdapter = new SimpleSectionsAdapter(this, getActivity());

        // Set a drag listener
        // TODO jonas
        /*mAdapter.setDropListener(new DropListener() {
          @Override
          public void drop(int from, int to) {
            Log.d("nononsenseapps drag", "Position from " + from + " to " + to);
            
            final Task fromTask = new Task((Cursor) mAdapter.getItem(from));
            final Task toTask = new Task((Cursor) mAdapter.getItem(to));
            
            fromTask.moveTo(getActivity().getContentResolver(), toTask);
          }
        });*/
    }

    /**
     * Called to have the fragment instantiate its user interface view. This is optional, and
     * non-graphical fragments can return null (which is the default implementation).  This will be
     * called between {@link #onCreate(Bundle)} and {@link #onActivityCreated(Bundle)}. <p/> <p>If you
     * return a View from here, you will later be called in {@link #onDestroyView} when the view is
     * being released.
     *
     * @param inflater           The LayoutInflater object that can be used to inflate any views in the fragment,
     * @param container          If non-null, this is the parent view that the fragment's UI should be attached to.  The
     *                           fragment should not add the view itself, but this can be used to generate the LayoutParams
     *                           of the view.
     * @param savedInstanceState If non-null, this fragment is being re-constructed from a previous saved state as given
     *                           here.
     * @return Return the View for the fragment's UI, or null.
     */
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //return super.onCreateView(inflater, container, savedInstanceState);
        View rootView = inflater.inflate(R.layout.fragment_task_list, container, false);

        listView = (RecyclerView) rootView.findViewById(android.R.id.list);
        loadList();
        // ListView will only support scrolling ToolBar off-screen from Lollipop onwards.
        // RecyclerView does not have this limitation
        ViewCompat.setNestedScrollingEnabled(listView, true);

        // setup swipe to refresh
        mSwipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.swiperefresh);
        setupSwipeToRefresh();

        return rootView;
    }

    @Override
    public void onActivityCreated(final Bundle state) {
        super.onActivityCreated(state);

        // Get the global list settings
        final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());

        mCallback = new LoaderCallbacks<Cursor>() {
            @Override
            public Loader<Cursor> onCreateLoader(int id, Bundle arg1) {
                if (id == LOADER_CURRENT_LIST) {
                    return new CursorLoader(getActivity(), TaskList.getUri(mListId), TaskList.Columns.FIELDS, null,
                            null, null);
                } else {
                    // What sorting to use
                    Uri targetUri;
                    String sortSpec;

                    if (mSortType == null) {
                        mSortType = prefs.getString(getString(R.string.pref_sorttype),
                                getString(R.string.default_sorttype));
                    }

                    // All-view can't use manual sorting
                    if (mListId < 1 && mSortType.equals(getString(R.string.const_possubsort))) {
                        mSortType = getString(R.string.const_all_default_sorting);
                    }

                    if (mSortType.equals(getString(R.string.const_alphabetic))) {
                        targetUri = Task.URI;
                        sortSpec = getString(R.string.const_as_alphabetic, Task.Columns.TITLE);
                    } else if (mSortType.equals(getString(R.string.const_duedate))) {
                        targetUri = Task.URI_SECTIONED_BY_DATE;
                        sortSpec = null;
                    } else if (mSortType.equals(getString(R.string.const_modified))) {
                        targetUri = Task.URI;
                        sortSpec = Task.Columns.UPDATED + " DESC";
                    }
                    // manual sorting
                    else {
                        targetUri = Task.URI;
                        sortSpec = Task.Columns.LEFT;
                    }

                    String where = null;
                    String[] whereArgs = null;

                    if (mListId > 0) {
                        where = Task.Columns.DBLIST + " IS ?";
                        whereArgs = new String[] { Long.toString(mListId) };
                    }

                    return new CursorLoader(getActivity(), targetUri, Task.Columns.FIELDS, where, whereArgs,
                            sortSpec);
                }
            }

            @Override
            public void onLoadFinished(Loader<Cursor> loader, Cursor c) {
                if (loader.getId() == LOADER_TASKS) {
                    mAdapter.swapCursor(c);
                }
            }

            @Override
            public void onLoaderReset(Loader<Cursor> loader) {
                if (loader.getId() == LOADER_TASKS) {
                    mAdapter.swapCursor(null);
                }
            }
        };

        getLoaderManager().restartLoader(LOADER_TASKS, null, mCallback);
    }

    /**
     * Called when the fragment is visible to the user and actively running. This is generally tied to
     * {@link Activity#onResume() Activity.onResume} of the containing Activity's lifecycle.
     */
    @Override
    public void onResume() {
        super.onResume();
        // activate monitor
        if (syncStatusReceiver != null) {
            syncStatusReceiver.startMonitoring(getActivity(), this);
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }

    /**
     * Called when the Fragment is no longer resumed.  This is generally tied to {@link
     * Activity#onPause() Activity.onPause} of the containing Activity's lifecycle.
     */
    @Override
    public void onPause() {
        //mSwipeRefreshLayout.setRefreshing(false);// deactivate monitor
        if (syncStatusReceiver != null) {
            syncStatusReceiver.stopMonitoring();
        }

        super.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        getLoaderManager().destroyLoader(0);
    }

    @Override
    public void onDetach() {
        mListener = null;
        PreferenceManager.getDefaultSharedPreferences(getActivity())
                .unregisterOnSharedPreferenceChangeListener(this);
        super.onDetach();
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.fragment_tasklist, menu);
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        if (getActivity() instanceof MenuStateController) {
            final boolean visible = ((MenuStateController) getActivity()).childItemsVisible();

            menu.setGroupVisible(R.id.list_menu_group, visible);
            if (!visible) {
                if (mMode != null) {
                    mMode.finish();
                }
            }
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_clearcompleted:
            if (mListId != -1) {
                DialogDeleteCompletedTasks.showDialog(getFragmentManager(), mListId, null);
            }
            return true;
        default:
            return false;
        }
    }

    @Override
    public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
        if (isDetached()) {
            // Fix crash report
            return;
        }
        try {
            boolean reload = false;
            if (key.equals(getString(R.string.pref_sorttype))) {
                mSortType = null;
                reload = true;
            }

            if (reload && mCallback != null) {
                getLoaderManager().restartLoader(LOADER_TASKS, null, mCallback);
            }
        } catch (IllegalStateException ignored) {
            // Fix crash report
            // Might get a race condition where fragment is detached when getString is called
        }
    }

    /**
     * @param ongoing
     */
    @Override
    public void onSyncStartStop(boolean ongoing) {
        mSwipeRefreshLayout.setRefreshing(ongoing);
    }

    public ItemTouchHelper getTouchHelper() {
        return touchHelper;
    }

    public int getRowCount() {
        return mRowCount;
    }

    public String getSortType() {
        return mSortType;
    }

    public TaskListCallbacks getListener() {
        return mListener;
    }

    public SelectedItemHandler getSelectedItemHandler() {
        return selectedItemHandler;
    }

    public long getListId() {
        return mListId;
    }

    @Override
    public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
        actionMode.getMenuInflater().inflate(R.menu.fragment_tasklist_context, menu);
        return true;
    }

    @Override
    public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
        return false;
    }

    @Override
    public boolean onActionItemClicked(ActionMode actionMode, MenuItem item) {
        // Respond to clicks on the actions in the CAB
        final boolean finish;
        int itemId = item.getItemId();
        if (itemId == R.id.menu_delete) {
            deleteTasks(selectedItemHandler.getSelected());
            finish = true;
        } else if (itemId == R.id.menu_switch_list) {
            // show move to list dialog
            DialogMoveToList.getInstance(selectedItemHandler.getSelected()).show(getFragmentManager(),
                    "move_to_list_dialog");
            finish = true;
        } else if (itemId == R.id.menu_share) {
            shareSelected(selectedItemHandler.getSelected());
            finish = true;
        } else {
            finish = false;
        }

        if (finish) {
            actionMode.finish(); // Action picked, so close the CAB
        }
        return finish;
    }

    private void shareSelected(Collection<Long> orgItemIds) {
        // This solves threading issues
        final long[] itemIds = ArrayHelper.toArray(orgItemIds);

        AsyncTaskHelper.background(new AsyncTaskHelper.Job() {
            @Override
            public void doInBackground() {
                final StringBuilder shareSubject = new StringBuilder();
                final StringBuilder shareText = new StringBuilder();

                final String whereId = new StringBuilder(Task.Columns._ID).append(" IN (")
                        .append(DAO.arrayToCommaString(itemIds)).append(")").toString();

                Cursor c = getContext().getContentResolver().query(Task.URI,
                        new String[] { Task.Columns._ID, Task.Columns.TITLE, Task.Columns.NOTE }, whereId, null,
                        null);

                if (c != null) {
                    while (c.moveToNext()) {
                        if (shareText.length() > 0) {
                            shareText.append("\n\n");
                        }
                        if (shareSubject.length() > 0) {
                            shareSubject.append(", ");
                        }

                        shareSubject.append(c.getString(1));
                        shareText.append(c.getString(1));

                        if (!c.getString(2).isEmpty()) {
                            shareText.append("\n").append(c.getString(2));
                        }
                    }

                    c.close();
                }

                final Intent shareIntent = new Intent(Intent.ACTION_SEND);
                shareIntent.setType("text/plain");
                shareIntent.putExtra(Intent.EXTRA_TEXT, shareText.toString());
                shareIntent.putExtra(Intent.EXTRA_SUBJECT, shareSubject.toString());
                startActivity(shareIntent);
            }
        });
    }

    @Override
    public void onDestroyActionMode(ActionMode actionMode) {
        //jonas
        selectedItemHandler.clear();
        mAdapter.notifyDataSetChanged();
    }

    /**
     * This interface must be implemented by activities that contain TaskListFragments to allow an
     * interaction in this fragment to be communicated to the activity and potentially other fragments
     * contained in that activity.
     */
    public interface TaskListCallbacks {
        void openTask(final Uri uri, final long listId, final View origin);
    }

    class DragHandler extends ItemTouchHelper.Callback {

        private static final String TAG = "DragHandler";

        public DragHandler() {
            super();
        }

        @Override
        public boolean isLongPressDragEnabled() {
            return false;
        }

        @Override
        public boolean isItemViewSwipeEnabled() {
            return false;
        }

        @Override
        public int getMovementFlags(final RecyclerView recyclerView, final RecyclerView.ViewHolder viewHolder) {
            int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
            int swipeFlags = 0;
            return makeMovementFlags(dragFlags, swipeFlags);
        }

        @Override
        public boolean onMove(final RecyclerView recyclerView, final RecyclerView.ViewHolder viewHolder,
                final RecyclerView.ViewHolder target) {
            final Task fromTask = new Task(mAdapter.getCursor(viewHolder.getAdapterPosition()));
            final Task toTask = new Task(mAdapter.getCursor(target.getAdapterPosition()));

            mAdapter.notifyItemMoved(viewHolder.getAdapterPosition(), target.getAdapterPosition());
            fromTask.moveTo(getActivity().getContentResolver(), toTask);
            return true;
        }

        @Override
        public void onSwiped(final RecyclerView.ViewHolder viewHolder, final int direction) {

        }
    }
}