diff --git a/DoNExt/app/src/main/AndroidManifest.xml b/DoNExt/app/src/main/AndroidManifest.xml index aecbbe8..ec826a3 100644 --- a/DoNExt/app/src/main/AndroidManifest.xml +++ b/DoNExt/app/src/main/AndroidManifest.xml @@ -14,6 +14,7 @@ android:theme="@style/AppTheme.NoActionBar"> + @@ -33,6 +34,14 @@ android:name="android.support.PARENT_ACTIVITY" android:value=".activities.MainActivity" /> + + + diff --git a/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/ItemTouchHelpers/TaskTouchHelper.java b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/ItemTouchHelpers/TaskTouchHelper.java new file mode 100644 index 0000000..f9c534d --- /dev/null +++ b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/ItemTouchHelpers/TaskTouchHelper.java @@ -0,0 +1,99 @@ +package com.wismna.geoffroy.donext.ItemTouchHelpers; + +import android.content.SharedPreferences; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.v4.app.FragmentManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.helper.ItemTouchHelper; +import android.view.View; + +import com.wismna.geoffroy.donext.activities.MainActivity; +import com.wismna.geoffroy.donext.adapters.TaskAdapter; +import com.wismna.geoffroy.donext.database.TaskDataAccess; +import com.wismna.geoffroy.donext.fragments.ConfirmDialogFragment; + +/** + * Created by geoffroy on 15-12-04. + */ +public class TaskTouchHelper extends ItemTouchHelper.SimpleCallback { + private TaskAdapter taskAdapter; + private TaskDataAccess taskDataAccess; + private FragmentManager fragmentManager; + + public TaskTouchHelper(TaskAdapter taskAdapter, TaskDataAccess taskDataAccess, FragmentManager fragmentManager){ + // No drag moves, only swipes + super(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT); + this.taskAdapter = taskAdapter; + this.taskDataAccess = taskDataAccess; + this.fragmentManager = fragmentManager; + } + + @Override + public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { + //TODO: Not implemented here + return false; + } + + @Override + public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(viewHolder.itemView.getContext()); + + int itemPosition = viewHolder.getAdapterPosition(); + + ConfirmDialogFragment confirmDialogFragment = ConfirmDialogFragment.newInstance(taskAdapter); + Bundle args = new Bundle(); + args.putInt("ItemPosition", itemPosition); + args.putInt("Direction", direction); + confirmDialogFragment.setArguments(args); + + String title = "Confirm"; + switch (direction) + { + // Mark item as Done + case ItemTouchHelper.LEFT: + boolean prefConfDone = sharedPref.getBoolean("pref_conf_done", true); + title = "Done"; + if (prefConfDone) confirmDialogFragment.show(fragmentManager, title); + else MainActivity.PerformSwipe(taskDataAccess, taskAdapter, itemPosition, direction); + break; + // Increase task cycle count + case ItemTouchHelper.RIGHT: + title = "Next"; + boolean prefConfNext = sharedPref.getBoolean("pref_conf_next", true); + if (prefConfNext) confirmDialogFragment.show(fragmentManager, title); + else MainActivity.PerformSwipe(taskDataAccess, taskAdapter, itemPosition, direction); + break; + } + } + + @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) { + // Get RecyclerView item from the ViewHolder + View itemView = viewHolder.itemView; + + Paint p = new Paint(); + if (dX > 0) { + /* Set your color for positive displacement */ + p.setARGB(255, 204, 229, 255); + + // Draw Rect with varying right side, equal to displacement dX + c.drawRect((float) itemView.getLeft(), (float) itemView.getTop(), dX, + (float) itemView.getBottom(), p); + } else { + /* Set your color for negative displacement */ + p.setARGB(255, 204, 255, 229); + + // Draw Rect with varying left side, equal to the item's right side plus negative displacement dX + c.drawRect((float) itemView.getRight() + dX, (float) itemView.getTop(), + (float) itemView.getRight(), (float) itemView.getBottom(), p); + } + + super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); + } + } +} diff --git a/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/activities/MainActivity.java b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/activities/MainActivity.java index f0b3dba..05e64a9 100644 --- a/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/activities/MainActivity.java +++ b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/activities/MainActivity.java @@ -3,7 +3,9 @@ package com.wismna.geoffroy.donext.activities; import android.app.Dialog; import android.app.DialogFragment; import android.content.Intent; +import android.content.SharedPreferences; import android.os.Bundle; +import android.preference.PreferenceManager; import android.support.design.widget.TabLayout; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; @@ -12,6 +14,7 @@ import android.support.v4.view.ViewPager; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; +import android.support.v7.widget.helper.ItemTouchHelper; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -27,12 +30,17 @@ import com.wismna.geoffroy.donext.dao.Task; import com.wismna.geoffroy.donext.dao.TaskList; import com.wismna.geoffroy.donext.database.TaskDataAccess; import com.wismna.geoffroy.donext.database.TaskListDataAccess; +import com.wismna.geoffroy.donext.fragments.ConfirmDialogFragment; import com.wismna.geoffroy.donext.fragments.NewTaskFragment; import com.wismna.geoffroy.donext.fragments.TasksFragment; import java.util.List; -public class MainActivity extends AppCompatActivity implements NewTaskFragment.NewTaskListener, TasksFragment.OnListFragmentInteractionListener { +public class MainActivity extends AppCompatActivity implements + NewTaskFragment.NewTaskListener, + TasksFragment.OnListFragmentInteractionListener, + ConfirmDialogFragment.ConfirmDialogListener +{ protected TaskDataAccess taskDataAccess; /** @@ -50,7 +58,6 @@ public class MainActivity extends AppCompatActivity implements NewTaskFragment.N */ private ViewPager mViewPager; - private TaskListDataAccess taskListDataAccess; private List taskLists; @Override @@ -70,7 +77,7 @@ public class MainActivity extends AppCompatActivity implements NewTaskFragment.N taskDataAccess.open(); // Access database to retrieve Tabs - taskListDataAccess = new TaskListDataAccess(this); + TaskListDataAccess taskListDataAccess = new TaskListDataAccess(this); taskListDataAccess.open(); taskLists = taskListDataAccess.getAllTaskLists(); @@ -83,6 +90,16 @@ public class MainActivity extends AppCompatActivity implements NewTaskFragment.N TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); tabLayout.setupWithViewPager(mViewPager); + // Add Task floating button + /*FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); + fab.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) + .setAction("Action", null).show(); + } + });*/ + } @Override public boolean onCreateOptionsMenu(Menu menu) { @@ -136,22 +153,20 @@ public class MainActivity extends AppCompatActivity implements NewTaskFragment.N TaskList taskList = (TaskList) listSpinner.getSelectedItem(); // Add the task to the database Task task = taskDataAccess.createTask( - nameText.getText().toString(), - descText.getText().toString(), - priorityRadio.getText().toString(), - taskList.getId()); + nameText.getText().toString(), + descText.getText().toString(), + priorityRadio.getText().toString(), + taskList.getId()); // Update the corresponding tab adapter TasksFragment taskFragment = (TasksFragment) mSectionsPagerAdapter.getRegisteredFragment(listSpinner.getSelectedItemPosition()); - TaskAdapter taskAdapter = ((TaskAdapter)((RecyclerView)taskFragment.getView()).getAdapter()); + TaskAdapter taskAdapter = ((TaskAdapter)((RecyclerView)taskFragment.getView().findViewById(R.id.task_list_view)).getAdapter()); taskAdapter.add(task, taskAdapter.getItemCount()); } - - @Override - public void onDialogNegativeClick(DialogFragment dialog) { - + /** Called when user clicks on the New Task floating button */ + public void onNewTaskClick(View view) { + OpenNewTaskDialog(); } - /** Called when the user clicks the Settings button */ public void openSettings(MenuItem menuItem) { Intent intent = new Intent(this, SettingsActivity.class); @@ -165,15 +180,7 @@ public class MainActivity extends AppCompatActivity implements NewTaskFragment.N /** Called when the user clicks the New Task button */ public void openNewTaskDialog(MenuItem menuItem) { - android.app.FragmentManager manager = getFragmentManager(); - NewTaskFragment newTaskFragment = new NewTaskFragment(); - - // Set current tab value to new task dialog - Bundle args = new Bundle(); - args.putInt("list", mViewPager.getCurrentItem()); - newTaskFragment.setArguments(args); - - newTaskFragment.show(manager, "Create new task"); + OpenNewTaskDialog(); } /** Will be called when the delete Task button is clicked */ @@ -187,6 +194,78 @@ public class MainActivity extends AppCompatActivity implements NewTaskFragment.N } + @Override + public void onDialogPositiveClick(android.support.v4.app.DialogFragment dialog) { + Bundle args = dialog.getArguments(); + int itemPosition = args.getInt("ItemPosition"); + int direction = args.getInt("Direction"); + + TaskAdapter taskAdapter = ((ConfirmDialogFragment)dialog).getTaskAdapter(); + PerformSwipe(taskDataAccess, taskAdapter, itemPosition, direction); + + } + + @Override + public void onDialogNeutralClick(android.support.v4.app.DialogFragment dialog) { + Bundle args = dialog.getArguments(); + int itemPosition = args.getInt("ItemPosition"); + int direction = args.getInt("Direction"); + + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); + SharedPreferences.Editor editor = sharedPref.edit(); + editor.putBoolean("pref_conf_next", false); + + switch (direction) + { + // Mark item as Done + case ItemTouchHelper.LEFT: + editor.putBoolean("pref_conf_done", false); + break; + // Increase task cycle count + case ItemTouchHelper.RIGHT: + editor.putBoolean("pref_conf_next", false); + break; + } + editor.commit(); + TaskAdapter taskAdapter = ((ConfirmDialogFragment)dialog).getTaskAdapter(); + PerformSwipe(taskDataAccess, taskAdapter, itemPosition, direction); + } + + private void OpenNewTaskDialog() { + android.app.FragmentManager manager = getFragmentManager(); + NewTaskFragment newTaskFragment = new NewTaskFragment(); + + // Set current tab value to new task dialog + Bundle args = new Bundle(); + args.putInt("list", mViewPager.getCurrentItem()); + newTaskFragment.setArguments(args); + + newTaskFragment.show(manager, "Create new task"); + } + + public static void PerformSwipe(TaskDataAccess taskDataAccess, TaskAdapter taskAdapter, int itemPosition, int direction) { + long itemId = taskAdapter.getItemId(itemPosition); + taskDataAccess.open(); + Task task = taskAdapter.getItem(itemPosition); + taskAdapter.remove(itemPosition); + + switch (direction) + { + // Mark item as Done + case ItemTouchHelper.LEFT: + taskDataAccess.setDone(itemId); + break; + // Increase task cycle count + case ItemTouchHelper.RIGHT: + int cycle = task.getCycle(); + taskDataAccess.increaseCycle(cycle, itemId); + task.setCycle(cycle + 1); + int lastPosition = taskAdapter.getItemCount(); + taskAdapter.add(task, lastPosition); + break; + } + taskDataAccess.close(); + } /** * A {@link FragmentPagerAdapter} that returns a fragment corresponding to * one of the sections/tabs/pages. diff --git a/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/activities/TaskDetailsActivity.java b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/activities/TaskDetailsActivity.java new file mode 100644 index 0000000..336e99c --- /dev/null +++ b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/activities/TaskDetailsActivity.java @@ -0,0 +1,15 @@ +package com.wismna.geoffroy.donext.activities; + +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; + +import com.wismna.geoffroy.donext.R; + +public class TaskDetailsActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_task_details); + } +} diff --git a/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/adapters/TaskAdapter.java b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/adapters/TaskAdapter.java index 220c73d..c9a969f 100644 --- a/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/adapters/TaskAdapter.java +++ b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/adapters/TaskAdapter.java @@ -45,11 +45,11 @@ public class TaskAdapter extends RecyclerView.Adapter { holder.mView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if (null != mListener) { - // Notify the active callbacks interface (the activity, if the - // fragment is attached to one) that an item has been selected. - mListener.onListFragmentInteraction(holder.mItem); - } + if (null != mListener) { + // Notify the active callbacks interface (the activity, if the + // fragment is attached to one) that an item has been selected. + mListener.onListFragmentInteraction(holder.mItem); + } } }); } @@ -59,17 +59,32 @@ public class TaskAdapter extends RecyclerView.Adapter { return mValues.size(); } + @Override + public long getItemId(int position) { + return getItem(position).getId(); + } + public void add(Task item, int position) { mValues.add(position, item); notifyItemInserted(position); } - public void remove(Task item) { - int position = mValues.indexOf(item); + public void remove(int position) { + //int position = mValues.indexOf(item); mValues.remove(position); notifyItemRemoved(position); } + public void update(Task item, int position) + { + mValues.set(position, item); + notifyItemChanged(position); + } + + public Task getItem(int position) { + return mValues.get(position); + } + public class ViewHolder extends RecyclerView.ViewHolder { public final View mView; public final TextView mIdView; diff --git a/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/database/TaskDataAccess.java b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/database/TaskDataAccess.java index 33a3389..62c5e7e 100644 --- a/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/database/TaskDataAccess.java +++ b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/database/TaskDataAccess.java @@ -40,6 +40,7 @@ public class TaskDataAccess { public void close() { dbHelper.close(); } + public Task createTask(String name, String description, String priority, long taskList) { ContentValues values = new ContentValues(); values.put(DatabaseHelper.TASKS_COLUMN_NAME, name); @@ -57,6 +58,10 @@ public class TaskDataAccess { return newTask; } + public void deleteTask(long taskId) { + + } + /*public Cursor deleteTask(Cursor taskCursor) { Task task = cursorToTask(taskCursor); long id = task.getId(); @@ -97,7 +102,9 @@ public class TaskDataAccess { Cursor cursor = database.rawQuery( "SELECT COUNT(*) " + " FROM " + DatabaseHelper.TASKS_TABLE_NAME + - " WHERE " + DatabaseHelper.TASKS_COLUMN_LIST + " = " + id, null); + " WHERE " + DatabaseHelper.TASKS_COLUMN_LIST + " = " + id + + " AND " + DatabaseHelper.TASKS_COLUMN_DONE + " = " + 0 + + " AND " + DatabaseHelper.TASKS_COLUMN_DELETED + " = " + 0, null); cursor.moveToFirst(); taskCount = cursor.getInt(0); cursor.close(); @@ -107,8 +114,10 @@ public class TaskDataAccess { int totalCycles = 0; Cursor cursor = database.rawQuery( "SELECT SUM(" + DatabaseHelper.TASKS_COLUMN_CYCLE + ") " + - " FROM " + DatabaseHelper.TASKS_TABLE_NAME + - " WHERE " + DatabaseHelper.TASKS_COLUMN_LIST + " = " + id, null); + " FROM " + DatabaseHelper.TASKS_TABLE_NAME + + " WHERE " + DatabaseHelper.TASKS_COLUMN_LIST + " = " + id + + " AND " + DatabaseHelper.TASKS_COLUMN_DONE + " = " + 0 + + " AND " + DatabaseHelper.TASKS_COLUMN_DELETED + " = " + 0, null); cursor.moveToFirst(); totalCycles = cursor.getInt(0); cursor.close(); @@ -120,8 +129,24 @@ public class TaskDataAccess { taskColumns, DatabaseHelper.COLUMN_ID + " = " + id, null, null, null, null); } public Cursor getAllTasksCursor(long id) { - return database.query(DatabaseHelper.TASKS_TABLE_NAME, - taskColumns, DatabaseHelper.TASKS_COLUMN_LIST + " = " + id, null, null, null, null); + return database.query(DatabaseHelper.TASKS_TABLE_NAME, taskColumns, + DatabaseHelper.TASKS_COLUMN_LIST + " = " + id + + " AND " + DatabaseHelper.TASKS_COLUMN_DONE + " = " + 0 + + " AND " + DatabaseHelper.TASKS_COLUMN_DELETED + " = " + 0, + null, null, null, + DatabaseHelper.TASKS_COLUMN_CYCLE + ", " + DatabaseHelper.COLUMN_ID + " ASC"); + } + + public int setDone(long id) { + ContentValues contentValues = new ContentValues(); + contentValues.put(DatabaseHelper.TASKS_COLUMN_DONE, 1); + return database.update(DatabaseHelper.TASKS_TABLE_NAME, contentValues, DatabaseHelper.COLUMN_ID + " = " + id, null); + } + + public int increaseCycle(int currentCycle, long id) { + ContentValues contentValues = new ContentValues(); + contentValues.put(DatabaseHelper.TASKS_COLUMN_CYCLE, currentCycle + 1); + return database.update(DatabaseHelper.TASKS_TABLE_NAME, contentValues, DatabaseHelper.COLUMN_ID + " = " + id, null); } private Task cursorToTask(Cursor cursor) { diff --git a/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/fragments/ConfirmDialogFragment.java b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/fragments/ConfirmDialogFragment.java new file mode 100644 index 0000000..e7e6beb --- /dev/null +++ b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/fragments/ConfirmDialogFragment.java @@ -0,0 +1,76 @@ +package com.wismna.geoffroy.donext.fragments; + +import android.app.Activity; +import android.app.Dialog; +import android.content.DialogInterface; +import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.support.v7.app.AlertDialog; + +import com.wismna.geoffroy.donext.R; +import com.wismna.geoffroy.donext.adapters.TaskAdapter; + +public class ConfirmDialogFragment extends DialogFragment { + public interface ConfirmDialogListener { + void onDialogPositiveClick(DialogFragment dialog); + void onDialogNeutralClick(DialogFragment dialog); + } + + private ConfirmDialogListener confirmDialogListener; + + private TaskAdapter taskAdapter; + + public static ConfirmDialogFragment newInstance(TaskAdapter taskAdapter) { + + Bundle args = new Bundle(); + + ConfirmDialogFragment fragment = new ConfirmDialogFragment(); + fragment.taskAdapter = taskAdapter; + fragment.setArguments(args); + return fragment; + } + + public TaskAdapter getTaskAdapter() { + return taskAdapter; + } + public void setTaskAdapter(TaskAdapter taskAdapter) { + this.taskAdapter = taskAdapter; + } + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + // Verify that the host activity implements the callback interface + try { + // Instantiate the NoticeDialogListener so we can send events to the host + confirmDialogListener = (ConfirmDialogListener) activity; + } catch (ClassCastException e) { + // The activity doesn't implement the interface, throw exception + throw new ClassCastException(activity.toString() + + " must implement NewTaskListener"); + } + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setMessage(R.string.task_swipe_confirmation_done) + .setPositiveButton(R.string.task_swipe_confirmation_yes, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + confirmDialogListener.onDialogPositiveClick(ConfirmDialogFragment.this); + } + }) + .setNegativeButton(R.string.task_swipe_confirmation_no, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + // User cancelled the dialog + } + }).setNeutralButton(R.string.task_swipe_confirmation_never, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + confirmDialogListener.onDialogNeutralClick(ConfirmDialogFragment.this); + } + } + ); + // Create the AlertDialog object and return it + return builder.create(); + } +} diff --git a/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/fragments/NewTaskFragment.java b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/fragments/NewTaskFragment.java index 43554b6..b263a34 100644 --- a/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/fragments/NewTaskFragment.java +++ b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/fragments/NewTaskFragment.java @@ -13,7 +13,6 @@ import android.widget.Spinner; import com.wismna.geoffroy.donext.R; import com.wismna.geoffroy.donext.dao.TaskList; -import com.wismna.geoffroy.donext.database.TaskDataAccess; import com.wismna.geoffroy.donext.database.TaskListDataAccess; import java.util.List; @@ -27,11 +26,11 @@ public class NewTaskFragment extends DialogFragment { * implement this interface in order to receive event callbacks. * Each method passes the DialogFragment in case the host needs to query it. */ public interface NewTaskListener { - public void onDialogPositiveClick(DialogFragment dialog); - public void onDialogNegativeClick(DialogFragment dialog); + void onDialogPositiveClick(DialogFragment dialog); + //void onDialogNegativeClick(DialogFragment dialog); } - private TaskDataAccess taskDataAccess; + //private TaskDataAccess taskDataAccess; // Use this instance of the interface to deliver action events private NewTaskListener mListener; diff --git a/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/fragments/TaskDetailsFragment.java b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/fragments/TaskDetailsFragment.java new file mode 100644 index 0000000..612f9ff --- /dev/null +++ b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/fragments/TaskDetailsFragment.java @@ -0,0 +1,109 @@ +package com.wismna.geoffroy.donext.fragments; + +import android.content.Context; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import com.wismna.geoffroy.donext.R; + +/** + * A simple {@link Fragment} subclass. + * Activities that contain this fragment must implement the + * {@link TaskDetailsFragment.OnFragmentInteractionListener} interface + * to handle interaction events. + * Use the {@link TaskDetailsFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class TaskDetailsFragment extends Fragment { + // TODO: Rename parameter arguments, choose names that match + // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER + private static final String ARG_PARAM1 = "param1"; + private static final String ARG_PARAM2 = "param2"; + + // TODO: Rename and change types of parameters + private String mParam1; + private String mParam2; + + private OnFragmentInteractionListener mListener; + + public TaskDetailsFragment() { + // Required empty public constructor + } + + /** + * Use this factory method to create a new instance of + * this fragment using the provided parameters. + * + * @param param1 Parameter 1. + * @param param2 Parameter 2. + * @return A new instance of fragment TaskDetailsFragment. + */ + // TODO: Rename and change types and number of parameters + public static TaskDetailsFragment newInstance(String param1, String param2) { + TaskDetailsFragment fragment = new TaskDetailsFragment(); + Bundle args = new Bundle(); + args.putString(ARG_PARAM1, param1); + args.putString(ARG_PARAM2, param2); + fragment.setArguments(args); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (getArguments() != null) { + mParam1 = getArguments().getString(ARG_PARAM1); + mParam2 = getArguments().getString(ARG_PARAM2); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_task_details, container, false); + } + + // TODO: Rename method, update argument and hook method into UI event + public void onButtonPressed(Uri uri) { + if (mListener != null) { + mListener.onFragmentInteraction(uri); + } + } + + @Override + public void onAttach(Context context) { + super.onAttach(context); + if (context instanceof OnFragmentInteractionListener) { + mListener = (OnFragmentInteractionListener) context; + } else { + throw new RuntimeException(context.toString() + + " must implement OnFragmentInteractionListener"); + } + } + + @Override + public void onDetach() { + super.onDetach(); + mListener = null; + } + + /** + * This interface must be implemented by activities that contain this + * fragment to allow an interaction in this fragment to be communicated + * to the activity and potentially other fragments contained in that + * activity. + *

+ * See the Android Training lesson Communicating with Other Fragments for more information. + */ + public interface OnFragmentInteractionListener { + // TODO: Update argument type and name + void onFragmentInteraction(Uri uri); + } +} diff --git a/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/fragments/TasksFragment.java b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/fragments/TasksFragment.java index 813da10..631950d 100644 --- a/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/fragments/TasksFragment.java +++ b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/fragments/TasksFragment.java @@ -5,12 +5,14 @@ import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.helper.ItemTouchHelper; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import android.widget.Toast; +import com.wismna.geoffroy.donext.ItemTouchHelpers.TaskTouchHelper; import com.wismna.geoffroy.donext.R; import com.wismna.geoffroy.donext.adapters.TaskAdapter; import com.wismna.geoffroy.donext.dao.Task; @@ -25,7 +27,6 @@ import com.wismna.geoffroy.donext.listeners.RecyclerItemClickListener; */ public class TasksFragment extends Fragment { - private TaskDataAccess taskDataAccess; private static final String TASK_LIST_ID = "task_list_id"; private long taskListId = -1; private OnListFragmentInteractionListener mListener; @@ -59,26 +60,13 @@ public class TasksFragment extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_task_list, container, false); - - // Set the adapter final Context context = view.getContext(); + + // Set the Recycler view RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.task_list_view); - - final Toast mToast = Toast.makeText(getActivity(), "", Toast.LENGTH_SHORT); recyclerView.setLayoutManager(new LinearLayoutManager(context)); - recyclerView.addOnItemTouchListener( - new RecyclerItemClickListener(context, new RecyclerItemClickListener.OnItemClickListener() { - @Override - public void onItemClick(View view, int position) { - // TODO: implement on item click event - TextView editText = (TextView) view.findViewById(R.id.task_id); - mToast.setText("Item " + editText.getText() + " clicked!"); - mToast.show(); - } - }) - ); - taskDataAccess = new TaskDataAccess(view.getContext()); + TaskDataAccess taskDataAccess = new TaskDataAccess(view.getContext()); taskDataAccess.open(); // Set total cycles @@ -92,6 +80,30 @@ public class TasksFragment extends Fragment { // Set RecyclerView Adapter TaskAdapter taskAdapter = new TaskAdapter(taskDataAccess.getAllTasks(taskListId), mListener); recyclerView.setAdapter(taskAdapter); + + taskDataAccess.close(); + + // Set ItemTouch helper in RecyclerView to handle swipe move on elements + // TODO: conflicts with ItemTouchListener, see why + ItemTouchHelper.Callback callback = new TaskTouchHelper(taskAdapter, taskDataAccess, getFragmentManager()); + ItemTouchHelper helper = new ItemTouchHelper(callback); + helper.attachToRecyclerView(recyclerView); + + // Implements touch listener to add click detection + // TODO: conflicts with ItemTouchHelper (maybe add swipe detection there with onFling?) + final Toast mToast = Toast.makeText(getActivity(), "", Toast.LENGTH_SHORT); + recyclerView.addOnItemTouchListener( + new RecyclerItemClickListener(context, new RecyclerItemClickListener.OnItemClickListener() { + @Override + public void onItemClick(View view, int position) { + // TODO: implement on item click event + TextView editText = (TextView) view.findViewById(R.id.task_id); + //Toast mToast = Toast.makeText(context, "Item " + editText.getText() + " clicked!", Toast.LENGTH_SHORT); + mToast.setText("Item " + editText.getText() + " clicked!"); + mToast.show(); + } + }) + ); return view; } diff --git a/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/listeners/RecyclerItemClickListener.java b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/listeners/RecyclerItemClickListener.java index 18246d8..214e9d3 100644 --- a/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/listeners/RecyclerItemClickListener.java +++ b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/listeners/RecyclerItemClickListener.java @@ -31,14 +31,17 @@ public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListen @Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) { View childView = view.findChildViewUnder(e.getX(), e.getY()); + int childId = view.getChildAdapterPosition(childView); if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) { mListener.onItemClick(childView, view.getChildAdapterPosition(childView)); } - return false; + // Allows swipe moves only on first element of the list + return childId != 0; } @Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { + } @Override diff --git a/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/widgets/NonSwipeableViewPager.java b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/widgets/NonSwipeableViewPager.java new file mode 100644 index 0000000..71e3a4e --- /dev/null +++ b/DoNExt/app/src/main/java/com/wismna/geoffroy/donext/widgets/NonSwipeableViewPager.java @@ -0,0 +1,32 @@ +package com.wismna.geoffroy.donext.widgets; + +import android.content.Context; +import android.support.v4.view.ViewPager; +import android.util.AttributeSet; +import android.view.MotionEvent; + +/** + * Created by geoffroy on 15-12-04. + */ +public class NonSwipeableViewPager extends ViewPager { + + public NonSwipeableViewPager(Context context) { + super(context); + } + + public NonSwipeableViewPager(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent event) { + // Never allow swiping to switch between pages + return false; + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + // Never allow swiping to switch between pages + return false; + } +} diff --git a/DoNExt/app/src/main/res/layout/activity_main.xml b/DoNExt/app/src/main/res/layout/activity_main.xml index 8699855..be78694 100644 --- a/DoNExt/app/src/main/res/layout/activity_main.xml +++ b/DoNExt/app/src/main/res/layout/activity_main.xml @@ -30,10 +30,18 @@ - + diff --git a/DoNExt/app/src/main/res/layout/activity_task_details.xml b/DoNExt/app/src/main/res/layout/activity_task_details.xml new file mode 100644 index 0000000..1f16065 --- /dev/null +++ b/DoNExt/app/src/main/res/layout/activity_task_details.xml @@ -0,0 +1,16 @@ + + + + diff --git a/DoNExt/app/src/main/res/layout/fragment_task.xml b/DoNExt/app/src/main/res/layout/fragment_task.xml index b1b0e59..bb2ec99 100644 --- a/DoNExt/app/src/main/res/layout/fragment_task.xml +++ b/DoNExt/app/src/main/res/layout/fragment_task.xml @@ -1,8 +1,9 @@ + android:layout_width="match_parent" + android:layout_height="?listPreferredItemHeight" + android:orientation="horizontal" + android:foreground="?selectableItemBackground" > + + + + diff --git a/DoNExt/app/src/main/res/values/strings.xml b/DoNExt/app/src/main/res/values/strings.xml index 227ef33..12ae1ba 100644 --- a/DoNExt/app/src/main/res/values/strings.xml +++ b/DoNExt/app/src/main/res/values/strings.xml @@ -26,6 +26,16 @@ Save Cancel + + Details + + + Confirm + Mark task as Done? + Mark task as Nexted? + Yes + No + Never ask again Confirm on DoNext? @@ -42,4 +52,7 @@ 7 TaskListActivity + + + Hello blank fragment