Split ListHabitsFragment into smaller classes

pull/30/head
Alinson S. Xavier 10 years ago
parent 0c0ac9dee5
commit c8c4df6ef7

@ -0,0 +1,268 @@
/* Copyright (C) 2016 Alinson Santos Xavier
*
* 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 org.isoron.uhabits.dialogs;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ProgressBar;
import com.android.colorpicker.ColorPickerDialog;
import com.android.colorpicker.ColorPickerSwatch;
import org.isoron.helpers.ColorHelper;
import org.isoron.helpers.DialogHelper;
import org.isoron.helpers.ReplayableActivity;
import org.isoron.uhabits.R;
import org.isoron.uhabits.commands.ArchiveHabitsCommand;
import org.isoron.uhabits.commands.ChangeHabitColorCommand;
import org.isoron.uhabits.commands.DeleteHabitsCommand;
import org.isoron.uhabits.commands.UnarchiveHabitsCommand;
import org.isoron.uhabits.fragments.EditHabitFragment;
import org.isoron.uhabits.io.CSVExporter;
import org.isoron.uhabits.loaders.HabitListLoader;
import org.isoron.uhabits.models.Habit;
import java.io.File;
import java.util.LinkedList;
import java.util.List;
public class HabitSelectionCallback implements ActionMode.Callback
{
private HabitListLoader loader;
private List<Integer> selectedPositions;
private ReplayableActivity activity;
private Listener listener;
private DialogHelper.OnSavedListener onSavedListener;
private ProgressBar progressBar;
public interface Listener
{
void onActionModeDestroyed(ActionMode mode);
}
public HabitSelectionCallback(ReplayableActivity activity, HabitListLoader loader)
{
this.activity = activity;
this.loader = loader;
selectedPositions = new LinkedList<>();
}
public void setListener(Listener listener)
{
this.listener = listener;
}
public void setProgressBar(ProgressBar progressBar)
{
this.progressBar = progressBar;
}
public void setOnSavedListener(DialogHelper.OnSavedListener onSavedListener)
{
this.onSavedListener = onSavedListener;
}
public void setSelectedPositions(List<Integer> selectedPositions)
{
this.selectedPositions = selectedPositions;
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu)
{
activity.getMenuInflater().inflate(R.menu.list_habits_context, menu);
updateTitle(mode);
updateActions(menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu)
{
updateTitle(mode);
updateActions(menu);
return true;
}
private void updateActions(Menu menu)
{
boolean showEdit = (selectedPositions.size() == 1);
boolean showColor = true;
boolean showArchive = true;
boolean showUnarchive = true;
if (showEdit) showColor = false;
for (int i : selectedPositions)
{
Habit h = loader.habitsList.get(i);
if (h.isArchived())
{
showColor = false;
showArchive = false;
}
else showUnarchive = false;
}
MenuItem itemEdit = menu.findItem(R.id.action_edit_habit);
MenuItem itemColor = menu.findItem(R.id.action_color);
MenuItem itemArchive = menu.findItem(R.id.action_archive_habit);
MenuItem itemUnarchive = menu.findItem(R.id.action_unarchive_habit);
itemEdit.setVisible(showEdit);
itemColor.setVisible(showColor);
itemArchive.setVisible(showArchive);
itemUnarchive.setVisible(showUnarchive);
}
private void updateTitle(ActionMode mode)
{
mode.setTitle("" + selectedPositions.size());
}
@Override
public boolean onActionItemClicked(final ActionMode mode, MenuItem item)
{
final LinkedList<Habit> selectedHabits = new LinkedList<>();
for (int i : selectedPositions)
selectedHabits.add(loader.habitsList.get(i));
Habit firstHabit = selectedHabits.getFirst();
switch (item.getItemId())
{
case R.id.action_archive_habit:
activity.executeCommand(new ArchiveHabitsCommand(selectedHabits), null);
mode.finish();
return true;
case R.id.action_unarchive_habit:
activity.executeCommand(new UnarchiveHabitsCommand(selectedHabits), null);
mode.finish();
return true;
case R.id.action_edit_habit:
{
EditHabitFragment frag = EditHabitFragment.editSingleHabitFragment(firstHabit.getId());
frag.setOnSavedListener(onSavedListener);
frag.show(activity.getFragmentManager(), "dialog");
return true;
}
case R.id.action_color:
{
ColorPickerDialog picker = ColorPickerDialog.newInstance(R.string.color_picker_default_title,
ColorHelper.palette, firstHabit.color, 4, ColorPickerDialog.SIZE_SMALL);
picker.setOnColorSelectedListener(new ColorPickerSwatch.OnColorSelectedListener()
{
public void onColorSelected(int color)
{
activity.executeCommand(
new ChangeHabitColorCommand(selectedHabits, color), null);
mode.finish();
}
});
picker.show(activity.getFragmentManager(), "picker");
return true;
}
case R.id.action_delete:
{
new AlertDialog.Builder(activity).setTitle(R.string.delete_habits)
.setMessage(R.string.delete_habits_message)
.setPositiveButton(android.R.string.yes,
new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
activity.executeCommand(
new DeleteHabitsCommand(selectedHabits), null);
mode.finish();
}
}).setNegativeButton(android.R.string.no, null)
.show();
return true;
}
case R.id.action_export_csv:
{
onExportHabitsClick(selectedHabits);
return true;
}
}
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode)
{
if(listener != null) listener.onActionModeDestroyed(mode);
}
private void onExportHabitsClick(final LinkedList<Habit> selectedHabits)
{
new AsyncTask<Void, Void, Void>()
{
String filename;
@Override
protected void onPreExecute()
{
if(progressBar != null)
{
progressBar.setIndeterminate(true);
progressBar.setVisibility(View.VISIBLE);
}
}
@Override
protected void onPostExecute(Void aVoid)
{
if(filename != null)
{
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setType("application/zip");
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(filename)));
activity.startActivity(intent);
}
if(progressBar != null)
progressBar.setVisibility(View.GONE);
}
@Override
protected Void doInBackground(Void... params)
{
CSVExporter exporter = new CSVExporter(activity, selectedHabits);
filename = exporter.writeArchive();
return null;
}
}.execute();
}
}

@ -0,0 +1,78 @@
/* Copyright (C) 2016 Alinson Santos Xavier
*
* 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 org.isoron.uhabits.dialogs;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.TextView;
import org.isoron.helpers.DateHelper;
import org.isoron.uhabits.R;
public class HintManager
{
private Context context;
private SharedPreferences prefs;
private View hintView;
public HintManager(Context context, View hintView)
{
this.context = context;
this.hintView = hintView;
prefs = PreferenceManager.getDefaultSharedPreferences(context);
}
public void dismissHint()
{
hintView.animate().alpha(0f).setDuration(500).setListener(new AnimatorListenerAdapter()
{
@Override
public void onAnimationEnd(Animator animation)
{
hintView.setVisibility(View.GONE);
}
});
}
public void showHintIfAppropriate()
{
Integer lastHintNumber = prefs.getInt("last_hint_number", -1);
Long lastHintTimestamp = prefs.getLong("last_hint_timestamp", -1);
if (DateHelper.getStartOfToday() > lastHintTimestamp) showHint(lastHintNumber + 1);
}
private void showHint(int hintNumber)
{
String[] hints = context.getResources().getStringArray(R.array.hints);
if (hintNumber >= hints.length) return;
prefs.edit().putInt("last_hint_number", hintNumber).apply();
prefs.edit().putLong("last_hint_timestamp", DateHelper.getStartOfToday()).apply();
TextView tvContent = (TextView) hintView.findViewById(R.id.hintContent);
tvContent.setText(hints[hintNumber]);
hintView.setAlpha(0.0f);
hintView.setVisibility(View.VISIBLE);
hintView.animate().alpha(1f).setDuration(500);
}
}

@ -70,7 +70,7 @@ public class EditHabitFragment extends DialogFragment
private SharedPreferences prefs; private SharedPreferences prefs;
private boolean is24HourMode; private boolean is24HourMode;
static EditHabitFragment editSingleHabitFragment(long id) public static EditHabitFragment editSingleHabitFragment(long id)
{ {
EditHabitFragment frag = new EditHabitFragment(); EditHabitFragment frag = new EditHabitFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();
@ -80,7 +80,7 @@ public class EditHabitFragment extends DialogFragment
return frag; return frag;
} }
static EditHabitFragment createHabitFragment() public static EditHabitFragment createHabitFragment()
{ {
EditHabitFragment frag = new EditHabitFragment(); EditHabitFragment frag = new EditHabitFragment();
Bundle args = new Bundle(); Bundle args = new Bundle();

@ -16,19 +16,12 @@
package org.isoron.uhabits.fragments; package org.isoron.uhabits.fragments;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog;
import android.app.Fragment; import android.app.Fragment;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
@ -53,31 +46,24 @@ import android.widget.LinearLayout.LayoutParams;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import com.android.colorpicker.ColorPickerDialog;
import com.android.colorpicker.ColorPickerSwatch;
import com.mobeta.android.dslv.DragSortController; import com.mobeta.android.dslv.DragSortController;
import com.mobeta.android.dslv.DragSortListView; import com.mobeta.android.dslv.DragSortListView;
import com.mobeta.android.dslv.DragSortListView.DropListener; import com.mobeta.android.dslv.DragSortListView.DropListener;
import org.isoron.helpers.ColorHelper;
import org.isoron.helpers.Command; import org.isoron.helpers.Command;
import org.isoron.helpers.DateHelper; import org.isoron.helpers.DateHelper;
import org.isoron.helpers.DialogHelper; import org.isoron.helpers.DialogHelper;
import org.isoron.helpers.DialogHelper.OnSavedListener; import org.isoron.helpers.DialogHelper.OnSavedListener;
import org.isoron.helpers.ReplayableActivity; import org.isoron.helpers.ReplayableActivity;
import org.isoron.uhabits.R; import org.isoron.uhabits.R;
import org.isoron.uhabits.commands.ArchiveHabitsCommand;
import org.isoron.uhabits.commands.ChangeHabitColorCommand;
import org.isoron.uhabits.commands.DeleteHabitsCommand;
import org.isoron.uhabits.commands.ToggleRepetitionCommand; import org.isoron.uhabits.commands.ToggleRepetitionCommand;
import org.isoron.uhabits.commands.UnarchiveHabitsCommand; import org.isoron.uhabits.dialogs.HabitSelectionCallback;
import org.isoron.uhabits.dialogs.HintManager;
import org.isoron.uhabits.helpers.ReminderHelper; import org.isoron.uhabits.helpers.ReminderHelper;
import org.isoron.uhabits.io.CSVExporter;
import org.isoron.uhabits.loaders.HabitListLoader; import org.isoron.uhabits.loaders.HabitListLoader;
import org.isoron.uhabits.models.Habit; import org.isoron.uhabits.models.Habit;
import org.isoron.uhabits.models.Score; import org.isoron.uhabits.models.Score;
import java.io.File;
import java.util.Date; import java.util.Date;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.LinkedList; import java.util.LinkedList;
@ -85,156 +71,13 @@ import java.util.List;
public class ListHabitsFragment extends Fragment public class ListHabitsFragment extends Fragment
implements OnSavedListener, OnItemClickListener, OnLongClickListener, DropListener, implements OnSavedListener, OnItemClickListener, OnLongClickListener, DropListener,
OnClickListener, HabitListLoader.Listener, AdapterView.OnItemLongClickListener OnClickListener, HabitListLoader.Listener, AdapterView.OnItemLongClickListener,
HabitSelectionCallback.Listener
{ {
private class ListHabitsActionBarCallback implements ActionMode.Callback
{
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu)
{
getActivity().getMenuInflater().inflate(R.menu.list_habits_context, menu);
updateTitle(mode);
updateActions(menu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu)
{
updateTitle(mode);
updateActions(menu);
return true;
}
private void updateActions(Menu menu)
{
boolean showEdit = (selectedPositions.size() == 1);
boolean showColor = true;
boolean showArchive = true;
boolean showUnarchive = true;
if(showEdit) showColor = false;
for(int i : selectedPositions)
{
Habit h = loader.habitsList.get(i);
if(h.isArchived())
{
showColor = false;
showArchive = false;
}
else showUnarchive = false;
}
MenuItem itemEdit = menu.findItem(R.id.action_edit_habit);
MenuItem itemColor = menu.findItem(R.id.action_color);
MenuItem itemArchive = menu.findItem(R.id.action_archive_habit);
MenuItem itemUnarchive = menu.findItem(R.id.action_unarchive_habit);
itemEdit.setVisible(showEdit);
itemColor.setVisible(showColor);
itemArchive.setVisible(showArchive);
itemUnarchive.setVisible(showUnarchive);
}
private void updateTitle(ActionMode mode)
{
mode.setTitle("" + selectedPositions.size());
}
@Override
public boolean onActionItemClicked(final ActionMode mode, MenuItem item)
{
final LinkedList<Habit> selectedHabits = new LinkedList<>();
for(int i : selectedPositions)
selectedHabits.add(loader.habitsList.get(i));
Habit firstHabit = selectedHabits.getFirst();
switch(item.getItemId())
{
case R.id.action_archive_habit:
executeCommand(new ArchiveHabitsCommand(selectedHabits), null);
mode.finish();
return true;
case R.id.action_unarchive_habit:
executeCommand(new UnarchiveHabitsCommand(selectedHabits), null);
mode.finish();
return true;
case R.id.action_edit_habit:
{
EditHabitFragment frag = EditHabitFragment.editSingleHabitFragment(firstHabit.getId());
frag.setOnSavedListener(ListHabitsFragment.this);
frag.show(getFragmentManager(), "dialog");
return true;
}
case R.id.action_color:
{
ColorPickerDialog picker = ColorPickerDialog.newInstance(
R.string.color_picker_default_title, ColorHelper.palette,
firstHabit.color, 4, ColorPickerDialog.SIZE_SMALL);
picker.setOnColorSelectedListener(new ColorPickerSwatch.OnColorSelectedListener()
{
public void onColorSelected(int color)
{
executeCommand(new ChangeHabitColorCommand(selectedHabits, color), null);
mode.finish();
}
});
picker.show(getFragmentManager(), "picker");
return true;
}
case R.id.action_delete:
{
new AlertDialog.Builder(activity)
.setTitle(R.string.delete_habits)
.setMessage(R.string.delete_habits_message)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
executeCommand(new DeleteHabitsCommand(selectedHabits), null);
mode.finish();
}
}).setNegativeButton(android.R.string.no, null)
.show();
return true;
}
case R.id.action_export_csv:
{
onExportHabitsClick(selectedHabits);
return true;
}
}
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode)
{
actionMode = null;
selectedPositions.clear();
adapter.notifyDataSetChanged();
listView.setDragEnabled(true);
}
}
public static final int INACTIVE_COLOR = Color.rgb(200, 200, 200); public static final int INACTIVE_COLOR = Color.rgb(200, 200, 200);
public static final int INACTIVE_CHECKMARK_COLOR = Color.rgb(230, 230, 230); public static final int INACTIVE_CHECKMARK_COLOR = Color.rgb(230, 230, 230);
public static final int HINT_INTERVAL = 5;
public static final int HINT_INTERVAL_OFFSET = 2;
public interface OnHabitClickListener public interface OnHabitClickListener
{ {
void onHabitClicked(Habit habit); void onHabitClicked(Habit habit);
@ -249,7 +92,6 @@ public class ListHabitsFragment extends Fragment
private int tvNameWidth; private int tvNameWidth;
private int buttonCount; private int buttonCount;
private View llEmpty; private View llEmpty;
private View llHint;
private OnHabitClickListener habitClickListener; private OnHabitClickListener habitClickListener;
private boolean isShortToggleEnabled; private boolean isShortToggleEnabled;
@ -260,9 +102,10 @@ public class ListHabitsFragment extends Fragment
private ActionMode actionMode; private ActionMode actionMode;
private List<Integer> selectedPositions; private List<Integer> selectedPositions;
private DragSortController dragSortController;
private ProgressBar progressBar; private ProgressBar progressBar;
private HintManager hintManager;
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) Bundle savedInstanceState)
@ -302,26 +145,29 @@ public class ListHabitsFragment extends Fragment
} }
}); });
dragSortController = new DragSortController(listView) { DragSortController dragSortController = new DragSortController(listView)
@Override {
public View onCreateFloatView(int position) @Override
{ public View onCreateFloatView(int position)
return adapter.getView(position, null, null); {
} return adapter.getView(position, null, null);
}
@Override @Override
public void onDestroyFloatView(View floatView) public void onDestroyFloatView(View floatView)
{ {
} }
}; };
dragSortController.setRemoveEnabled(false); dragSortController.setRemoveEnabled(false);
listView.setFloatViewManager(dragSortController); listView.setFloatViewManager(dragSortController);
listView.setDragEnabled(true); listView.setDragEnabled(true);
listView.setLongClickable(true); listView.setLongClickable(true);
llHint = view.findViewById(R.id.llHint); View llHint = view.findViewById(R.id.llHint);
llHint.setOnClickListener(this); llHint.setOnClickListener(this);
hintManager = new HintManager(activity, llHint);
Typeface fontawesome = Typeface.createFromAsset(getActivity().getAssets(), Typeface fontawesome = Typeface.createFromAsset(getActivity().getAssets(),
"fontawesome-webfont.ttf"); "fontawesome-webfont.ttf");
@ -332,7 +178,6 @@ public class ListHabitsFragment extends Fragment
setHasOptionsMenu(true); setHasOptionsMenu(true);
selectedPositions = new LinkedList<>(); selectedPositions = new LinkedList<>();
return view; return view;
} }
@ -358,7 +203,7 @@ public class ListHabitsFragment extends Fragment
updateEmptyMessage(); updateEmptyMessage();
updateHeader(); updateHeader();
showNextHint(); hintManager.showHintIfAppropriate();
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
isShortToggleEnabled = prefs.getBoolean("pref_short_toggle", false); isShortToggleEnabled = prefs.getBoolean("pref_short_toggle", false);
@ -485,8 +330,13 @@ public class ListHabitsFragment extends Fragment
if(actionMode == null) if(actionMode == null)
{ {
actionMode = getActivity().startActionMode(new ListHabitsActionBarCallback()); HabitSelectionCallback callback = new HabitSelectionCallback(activity, loader);
// listView.setDragEnabled(false); callback.setSelectedPositions(selectedPositions);
callback.setProgressBar(progressBar);
callback.setOnSavedListener(this);
callback.setListener(this);
actionMode = getActivity().startActionMode(callback);
} }
if(actionMode != null) actionMode.invalidate(); if(actionMode != null) actionMode.invalidate();
@ -555,43 +405,6 @@ public class ListHabitsFragment extends Fragment
activity.executeCommand(c, refreshKey); activity.executeCommand(c, refreshKey);
} }
private void hideHint()
{
llHint.animate().alpha(0f).setDuration(500).setListener(new AnimatorListenerAdapter()
{
@Override
public void onAnimationEnd(Animator animation)
{
llHint.setVisibility(View.GONE);
}
});
}
private void showNextHint()
{
Integer lastHintNumber = prefs.getInt("last_hint_number", -1);
Long lastHintTimestamp = prefs.getLong("last_hint_timestamp", -1);
if(DateHelper.getStartOfToday() > lastHintTimestamp)
showHint(lastHintNumber + 1);
}
private void showHint(int hintNumber)
{
String[] hints = activity.getResources().getStringArray(R.array.hints);
if(hintNumber >= hints.length) return;
prefs.edit().putInt("last_hint_number", hintNumber).apply();
prefs.edit().putLong("last_hint_timestamp", DateHelper.getStartOfToday()).apply();
TextView tvContent = (TextView) llHint.findViewById(R.id.hintContent);
tvContent.setText(hints[hintNumber]);
llHint.setAlpha(0.0f);
llHint.setVisibility(View.VISIBLE);
llHint.animate().alpha(1f).setDuration(500);
}
@Override @Override
public void drop(int from, int to) public void drop(int from, int to)
{ {
@ -614,7 +427,7 @@ public class ListHabitsFragment extends Fragment
break; break;
case R.id.llHint: case R.id.llHint:
hideHint(); hintManager.dismissHint();
break; break;
} }
} }
@ -798,42 +611,11 @@ public class ListHabitsFragment extends Fragment
else loader.updateHabit(refreshKey); else loader.updateHabit(refreshKey);
} }
private void onExportHabitsClick(final LinkedList<Habit> selectedHabits) public void onActionModeDestroyed(ActionMode mode)
{ {
new AsyncTask<Void, Void, Void>() actionMode = null;
{ selectedPositions.clear();
String filename; adapter.notifyDataSetChanged();
listView.setDragEnabled(true);
@Override
protected void onPreExecute()
{
progressBar.setIndeterminate(true);
progressBar.setVisibility(View.VISIBLE);
}
@Override
protected void onPostExecute(Void aVoid)
{
if(filename != null)
{
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setType("application/zip");
intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(filename)));
startActivity(intent);
}
progressBar.setVisibility(View.GONE);
}
@Override
protected Void doInBackground(Void... params)
{
CSVExporter exporter = new CSVExporter(activity, selectedHabits);
filename = exporter.writeArchive();
return null;
}
}.execute();
} }
} }

Loading…
Cancel
Save