mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-07 01:28:52 -06:00
ShowHabit: Refactor score chart
This commit is contained in:
@@ -30,9 +30,9 @@ import org.junit.runner.RunWith;
|
|||||||
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
@SmallTest
|
@SmallTest
|
||||||
public class HabitFrequencyViewTest extends BaseViewTest
|
public class FrequencyChartTest extends BaseViewTest
|
||||||
{
|
{
|
||||||
private HabitFrequencyView view;
|
private FrequencyChart view;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp()
|
public void setUp()
|
||||||
@@ -42,7 +42,7 @@ public class HabitFrequencyViewTest extends BaseViewTest
|
|||||||
fixtures.purgeHabits(habitList);
|
fixtures.purgeHabits(habitList);
|
||||||
Habit habit = fixtures.createLongHabit();
|
Habit habit = fixtures.createLongHabit();
|
||||||
|
|
||||||
view = new HabitFrequencyView(targetContext);
|
view = new FrequencyChart(targetContext);
|
||||||
view.setHabit(habit);
|
view.setHabit(habit);
|
||||||
refreshData(view);
|
refreshData(view);
|
||||||
measureView(dpToPixels(300), dpToPixels(100), view);
|
measureView(dpToPixels(300), dpToPixels(100), view);
|
||||||
@@ -40,7 +40,7 @@ public class HabitHistoryViewTest extends BaseViewTest
|
|||||||
{
|
{
|
||||||
private Habit habit;
|
private Habit habit;
|
||||||
|
|
||||||
private HabitHistoryView view;
|
private HistoryView view;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp()
|
public void setUp()
|
||||||
@@ -50,7 +50,7 @@ public class HabitHistoryViewTest extends BaseViewTest
|
|||||||
fixtures.purgeHabits(habitList);
|
fixtures.purgeHabits(habitList);
|
||||||
habit = fixtures.createLongHabit();
|
habit = fixtures.createLongHabit();
|
||||||
|
|
||||||
view = new HabitHistoryView(targetContext);
|
view = new HistoryView(targetContext);
|
||||||
view.setHabit(habit);
|
view.setHabit(habit);
|
||||||
measureView(dpToPixels(400), dpToPixels(200), view);
|
measureView(dpToPixels(400), dpToPixels(200), view);
|
||||||
refreshData(view);
|
refreshData(view);
|
||||||
|
|||||||
@@ -25,18 +25,20 @@ import android.util.Log;
|
|||||||
|
|
||||||
import org.isoron.uhabits.*;
|
import org.isoron.uhabits.*;
|
||||||
import org.isoron.uhabits.models.Habit;
|
import org.isoron.uhabits.models.Habit;
|
||||||
|
import org.isoron.uhabits.utils.*;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
@SmallTest
|
@SmallTest
|
||||||
public class HabitScoreViewTest extends BaseViewTest
|
public class ScoreChartTest extends BaseViewTest
|
||||||
{
|
{
|
||||||
private Habit habit;
|
private Habit habit;
|
||||||
|
|
||||||
private HabitScoreView view;
|
private ScoreChart view;
|
||||||
|
|
||||||
|
@Override
|
||||||
@Before
|
@Before
|
||||||
public void setUp()
|
public void setUp()
|
||||||
{
|
{
|
||||||
@@ -45,10 +47,10 @@ public class HabitScoreViewTest extends BaseViewTest
|
|||||||
fixtures.purgeHabits(habitList);
|
fixtures.purgeHabits(habitList);
|
||||||
habit = fixtures.createLongHabit();
|
habit = fixtures.createLongHabit();
|
||||||
|
|
||||||
view = new HabitScoreView(targetContext);
|
view = new ScoreChart(targetContext);
|
||||||
view.setHabit(habit);
|
view.setScores(habit.getScores().getAll());
|
||||||
|
view.setPrimaryColor(ColorUtils.getColor(targetContext, habit.getColor()));
|
||||||
view.setBucketSize(7);
|
view.setBucketSize(7);
|
||||||
refreshData(view);
|
|
||||||
measureView(dpToPixels(300), dpToPixels(200), view);
|
measureView(dpToPixels(300), dpToPixels(200), view);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,8 +81,8 @@ public class HabitScoreViewTest extends BaseViewTest
|
|||||||
@Test
|
@Test
|
||||||
public void testRender_withMonthlyBucket() throws Throwable
|
public void testRender_withMonthlyBucket() throws Throwable
|
||||||
{
|
{
|
||||||
|
view.setScores(habit.getScores().groupBy(DateUtils.TruncateField.MONTH));
|
||||||
view.setBucketSize(30);
|
view.setBucketSize(30);
|
||||||
view.refreshData();
|
|
||||||
view.invalidate();
|
view.invalidate();
|
||||||
|
|
||||||
assertRenders(view, "HabitScoreView/renderMonthly.png");
|
assertRenders(view, "HabitScoreView/renderMonthly.png");
|
||||||
@@ -96,8 +98,8 @@ public class HabitScoreViewTest extends BaseViewTest
|
|||||||
@Test
|
@Test
|
||||||
public void testRender_withYearlyBucket() throws Throwable
|
public void testRender_withYearlyBucket() throws Throwable
|
||||||
{
|
{
|
||||||
|
view.setScores(habit.getScores().groupBy(DateUtils.TruncateField.YEAR));
|
||||||
view.setBucketSize(365);
|
view.setBucketSize(365);
|
||||||
view.refreshData();
|
|
||||||
view.invalidate();
|
view.invalidate();
|
||||||
|
|
||||||
assertRenders(view, "HabitScoreView/renderYearly.png");
|
assertRenders(view, "HabitScoreView/renderYearly.png");
|
||||||
@@ -30,9 +30,9 @@ import org.junit.runner.RunWith;
|
|||||||
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
@SmallTest
|
@SmallTest
|
||||||
public class HabitStreakViewTest extends BaseViewTest
|
public class StreakChartTest extends BaseViewTest
|
||||||
{
|
{
|
||||||
private HabitStreakView view;
|
private StreakChart view;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Before
|
@Before
|
||||||
@@ -43,7 +43,7 @@ public class HabitStreakViewTest extends BaseViewTest
|
|||||||
fixtures.purgeHabits(habitList);
|
fixtures.purgeHabits(habitList);
|
||||||
Habit habit = fixtures.createLongHabit();
|
Habit habit = fixtures.createLongHabit();
|
||||||
|
|
||||||
view = new HabitStreakView(targetContext);
|
view = new StreakChart(targetContext);
|
||||||
measureView(dpToPixels(300), dpToPixels(100), view);
|
measureView(dpToPixels(300), dpToPixels(100), view);
|
||||||
|
|
||||||
view.setHabit(habit);
|
view.setHabit(habit);
|
||||||
@@ -44,6 +44,7 @@ public class MemoryScoreList extends ScoreList
|
|||||||
if (s.getTimestamp() >= timestamp) discard.add(s);
|
if (s.getTimestamp() >= timestamp) discard.add(s);
|
||||||
|
|
||||||
list.removeAll(discard);
|
list.removeAll(discard);
|
||||||
|
getObservable().notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -134,6 +134,8 @@ public class SQLiteScoreList extends ScoreList
|
|||||||
.where("habit = ?", habit.getId())
|
.where("habit = ?", habit.getId())
|
||||||
.and("timestamp >= ?", timestamp)
|
.and("timestamp >= ?", timestamp)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
|
getObservable().notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import org.isoron.uhabits.R;
|
|||||||
import org.isoron.uhabits.models.Habit;
|
import org.isoron.uhabits.models.Habit;
|
||||||
import org.isoron.uhabits.models.HabitList;
|
import org.isoron.uhabits.models.HabitList;
|
||||||
import org.isoron.uhabits.tasks.BaseTask;
|
import org.isoron.uhabits.tasks.BaseTask;
|
||||||
import org.isoron.uhabits.ui.habits.show.views.HabitHistoryView;
|
import org.isoron.uhabits.ui.habits.show.views.HistoryView;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ public class HistoryEditorDialog extends AppCompatDialogFragment
|
|||||||
|
|
||||||
private Listener listener;
|
private Listener listener;
|
||||||
|
|
||||||
HabitHistoryView historyView;
|
HistoryView historyView;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
HabitList habitList;
|
HabitList habitList;
|
||||||
@@ -53,7 +53,7 @@ public class HistoryEditorDialog extends AppCompatDialogFragment
|
|||||||
{
|
{
|
||||||
Context context = getActivity();
|
Context context = getActivity();
|
||||||
HabitsApplication.getComponent().inject(this);
|
HabitsApplication.getComponent().inject(this);
|
||||||
historyView = new HabitHistoryView(context, null);
|
historyView = new HistoryView(context, null);
|
||||||
|
|
||||||
if (savedInstanceState != null)
|
if (savedInstanceState != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,13 +22,11 @@ package org.isoron.uhabits.ui.habits.show;
|
|||||||
import android.os.*;
|
import android.os.*;
|
||||||
import android.support.v4.app.*;
|
import android.support.v4.app.*;
|
||||||
import android.view.*;
|
import android.view.*;
|
||||||
import android.widget.*;
|
|
||||||
|
|
||||||
import org.isoron.uhabits.*;
|
import org.isoron.uhabits.*;
|
||||||
import org.isoron.uhabits.models.*;
|
import org.isoron.uhabits.models.*;
|
||||||
import org.isoron.uhabits.ui.habits.edit.*;
|
import org.isoron.uhabits.ui.habits.edit.*;
|
||||||
import org.isoron.uhabits.ui.habits.show.views.*;
|
import org.isoron.uhabits.ui.habits.show.views.*;
|
||||||
import org.isoron.uhabits.utils.*;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -39,44 +37,33 @@ public class ShowHabitFragment extends Fragment
|
|||||||
{
|
{
|
||||||
Habit habit;
|
Habit habit;
|
||||||
|
|
||||||
float todayScore;
|
|
||||||
|
|
||||||
float lastMonthScore;
|
|
||||||
|
|
||||||
float lastYearScore;
|
|
||||||
|
|
||||||
int activeColor;
|
int activeColor;
|
||||||
|
|
||||||
int inactiveColor;
|
int inactiveColor;
|
||||||
|
|
||||||
int previousScoreInterval;
|
|
||||||
|
|
||||||
private ShowHabitHelper helper;
|
private ShowHabitHelper helper;
|
||||||
|
|
||||||
protected ShowHabitActivity activity;
|
protected ShowHabitActivity activity;
|
||||||
|
|
||||||
private List<HabitDataView> dataViews;
|
private List<HabitDataView> dataViews;
|
||||||
|
|
||||||
@BindView(R.id.sStrengthInterval)
|
|
||||||
Spinner sStrengthInterval;
|
|
||||||
|
|
||||||
@BindView(R.id.scoreView)
|
|
||||||
HabitScoreView habitScoreView;
|
|
||||||
|
|
||||||
@BindView(R.id.historyView)
|
@BindView(R.id.historyView)
|
||||||
HabitHistoryView habitHistoryView;
|
HistoryView historyView;
|
||||||
|
|
||||||
@BindView(R.id.punchcardView)
|
@BindView(R.id.punchcardView)
|
||||||
HabitFrequencyView habitFrequencyView;
|
FrequencyChart frequencyChart;
|
||||||
|
|
||||||
@BindView(R.id.streakView)
|
@BindView(R.id.streakChart)
|
||||||
HabitStreakView habitStreakView;
|
StreakChart streakChart;
|
||||||
|
|
||||||
@BindView(R.id.subtitle)
|
@BindView(R.id.subtitleCard)
|
||||||
SubtitleCardView subtitleView;
|
SubtitleCard subtitleCard;
|
||||||
|
|
||||||
@BindView(R.id.overview)
|
@BindView(R.id.overviewCard)
|
||||||
OverviewCardView overview;
|
OverviewCard overviewCard;
|
||||||
|
|
||||||
|
@BindView(R.id.strengthCard)
|
||||||
|
ScoreCard scoreCard;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater,
|
public View onCreateView(LayoutInflater inflater,
|
||||||
@@ -92,15 +79,6 @@ public class ShowHabitFragment extends Fragment
|
|||||||
habit = activity.getHabit();
|
habit = activity.getHabit();
|
||||||
helper.updateColors();
|
helper.updateColors();
|
||||||
|
|
||||||
int defaultScoreInterval =
|
|
||||||
InterfaceUtils.getDefaultScoreInterval(getContext());
|
|
||||||
previousScoreInterval = defaultScoreInterval;
|
|
||||||
setScoreBucketSize(defaultScoreInterval);
|
|
||||||
|
|
||||||
sStrengthInterval.setSelection(defaultScoreInterval);
|
|
||||||
sStrengthInterval.setOnItemSelectedListener(
|
|
||||||
new OnItemSelectedListener());
|
|
||||||
|
|
||||||
createDataViews();
|
createDataViews();
|
||||||
helper.updateCardHeaders(view);
|
helper.updateCardHeaders(view);
|
||||||
setHasOptionsMenu(true);
|
setHasOptionsMenu(true);
|
||||||
@@ -118,14 +96,14 @@ public class ShowHabitFragment extends Fragment
|
|||||||
|
|
||||||
private void createDataViews()
|
private void createDataViews()
|
||||||
{
|
{
|
||||||
subtitleView.setHabit(habit);
|
subtitleCard.setHabit(habit);
|
||||||
overview.setHabit(habit);
|
overviewCard.setHabit(habit);
|
||||||
|
scoreCard.setHabit(habit);
|
||||||
|
|
||||||
dataViews = new LinkedList<>();
|
dataViews = new LinkedList<>();
|
||||||
dataViews.add(habitScoreView);
|
dataViews.add(historyView);
|
||||||
dataViews.add(habitHistoryView);
|
dataViews.add(frequencyChart);
|
||||||
dataViews.add(habitFrequencyView);
|
dataViews.add(streakChart);
|
||||||
dataViews.add(habitStreakView);
|
|
||||||
|
|
||||||
for (HabitDataView dataView : dataViews)
|
for (HabitDataView dataView : dataViews)
|
||||||
dataView.setHabit(habit);
|
dataView.setHabit(habit);
|
||||||
@@ -156,17 +134,6 @@ public class ShowHabitFragment extends Fragment
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setScoreBucketSize(int position)
|
|
||||||
{
|
|
||||||
if (getView() == null) return;
|
|
||||||
|
|
||||||
habitScoreView.setBucketSize(
|
|
||||||
HabitScoreView.DEFAULT_BUCKET_SIZES[position]);
|
|
||||||
|
|
||||||
InterfaceUtils.setDefaultScoreInterval(getContext(), position);
|
|
||||||
previousScoreInterval = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onModelChange()
|
public void onModelChange()
|
||||||
{
|
{
|
||||||
@@ -190,23 +157,4 @@ public class ShowHabitFragment extends Fragment
|
|||||||
habit.getObservable().removeListener(this);
|
habit.getObservable().removeListener(this);
|
||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class OnItemSelectedListener
|
|
||||||
implements AdapterView.OnItemSelectedListener
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void onItemSelected(AdapterView<?> parent,
|
|
||||||
View view,
|
|
||||||
int position,
|
|
||||||
long id)
|
|
||||||
{
|
|
||||||
setScoreBucketSize(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onNothingSelected(AdapterView<?> parent)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ public class ShowHabitHelper
|
|||||||
void updateCardHeaders(View view)
|
void updateCardHeaders(View view)
|
||||||
{
|
{
|
||||||
updateColor(view, R.id.tvHistory);
|
updateColor(view, R.id.tvHistory);
|
||||||
updateColor(view, R.id.tvStrength);
|
|
||||||
updateColor(view, R.id.tvStreaks);
|
updateColor(view, R.id.tvStreaks);
|
||||||
updateColor(view, R.id.tvWeekdayFreq);
|
updateColor(view, R.id.tvWeekdayFreq);
|
||||||
updateColor(view, R.id.scoreLabel);
|
updateColor(view, R.id.scoreLabel);
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import org.isoron.uhabits.utils.*;
|
|||||||
import java.text.*;
|
import java.text.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class HabitFrequencyView extends ScrollableDataView
|
public class FrequencyChart extends ScrollableChart
|
||||||
implements HabitDataView, ModelObservable.Listener
|
implements HabitDataView, ModelObservable.Listener
|
||||||
{
|
{
|
||||||
private Paint pGrid;
|
private Paint pGrid;
|
||||||
@@ -70,13 +70,13 @@ public class HabitFrequencyView extends ScrollableDataView
|
|||||||
|
|
||||||
private HashMap<Long, Integer[]> frequency;
|
private HashMap<Long, Integer[]> frequency;
|
||||||
|
|
||||||
public HabitFrequencyView(Context context)
|
public FrequencyChart(Context context)
|
||||||
{
|
{
|
||||||
super(context);
|
super(context);
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public HabitFrequencyView(Context context, AttributeSet attrs)
|
public FrequencyChart(Context context, AttributeSet attrs)
|
||||||
{
|
{
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
this.primaryColor = ColorUtils.getColor(getContext(), 7);
|
this.primaryColor = ColorUtils.getColor(getContext(), 7);
|
||||||
@@ -33,10 +33,9 @@ import org.isoron.uhabits.utils.*;
|
|||||||
import java.text.*;
|
import java.text.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class HabitHistoryView extends ScrollableDataView implements
|
public class HistoryView extends ScrollableChart implements HabitDataView,
|
||||||
HabitDataView,
|
ToggleRepetitionTask.Listener,
|
||||||
ToggleRepetitionTask.Listener,
|
ModelObservable.Listener
|
||||||
ModelObservable.Listener
|
|
||||||
{
|
{
|
||||||
private Habit habit;
|
private Habit habit;
|
||||||
|
|
||||||
@@ -89,13 +88,13 @@ public class HabitHistoryView extends ScrollableDataView implements
|
|||||||
|
|
||||||
private float headerOverflow = 0;
|
private float headerOverflow = 0;
|
||||||
|
|
||||||
public HabitHistoryView(Context context)
|
public HistoryView(Context context)
|
||||||
{
|
{
|
||||||
super(context);
|
super(context);
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public HabitHistoryView(Context context, AttributeSet attrs)
|
public HistoryView(Context context, AttributeSet attrs)
|
||||||
{
|
{
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
init();
|
init();
|
||||||
@@ -169,6 +168,7 @@ public class HabitHistoryView extends ScrollableDataView implements
|
|||||||
postInvalidate();
|
postInvalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setHabit(Habit habit)
|
public void setHabit(Habit habit)
|
||||||
{
|
{
|
||||||
this.habit = habit;
|
this.habit = habit;
|
||||||
@@ -31,7 +31,7 @@ import org.isoron.uhabits.utils.*;
|
|||||||
|
|
||||||
import butterknife.*;
|
import butterknife.*;
|
||||||
|
|
||||||
public class OverviewCardView extends LinearLayout
|
public class OverviewCard extends LinearLayout
|
||||||
implements ModelObservable.Listener
|
implements ModelObservable.Listener
|
||||||
{
|
{
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -57,13 +57,13 @@ public class OverviewCardView extends LinearLayout
|
|||||||
|
|
||||||
private int color;
|
private int color;
|
||||||
|
|
||||||
public OverviewCardView(Context context)
|
public OverviewCard(Context context)
|
||||||
{
|
{
|
||||||
super(context);
|
super(context);
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public OverviewCardView(Context context, AttributeSet attrs)
|
public OverviewCard(Context context, AttributeSet attrs)
|
||||||
{
|
{
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
init();
|
init();
|
||||||
@@ -0,0 +1,198 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Loop Habit Tracker.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker 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.
|
||||||
|
*
|
||||||
|
* Loop Habit Tracker 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.ui.habits.show.views;
|
||||||
|
|
||||||
|
import android.content.*;
|
||||||
|
import android.support.annotation.*;
|
||||||
|
import android.util.*;
|
||||||
|
import android.widget.*;
|
||||||
|
|
||||||
|
import org.isoron.uhabits.*;
|
||||||
|
import org.isoron.uhabits.models.*;
|
||||||
|
import org.isoron.uhabits.tasks.*;
|
||||||
|
import org.isoron.uhabits.utils.*;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import butterknife.*;
|
||||||
|
|
||||||
|
public class ScoreCard extends RelativeLayout
|
||||||
|
implements ModelObservable.Listener
|
||||||
|
{
|
||||||
|
public static final int[] BUCKET_SIZES = { 1, 7, 31, 92, 365 };
|
||||||
|
|
||||||
|
@BindView(R.id.spinner)
|
||||||
|
Spinner spinner;
|
||||||
|
|
||||||
|
@BindView(R.id.scoreView)
|
||||||
|
ScoreChart chart;
|
||||||
|
|
||||||
|
@BindView(R.id.title)
|
||||||
|
TextView title;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Habit habit;
|
||||||
|
|
||||||
|
private int color;
|
||||||
|
|
||||||
|
private int bucketSize;
|
||||||
|
|
||||||
|
public ScoreCard(Context context)
|
||||||
|
{
|
||||||
|
super(context);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScoreCard(Context context, AttributeSet attrs)
|
||||||
|
{
|
||||||
|
super(context, attrs);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnItemSelected(R.id.spinner)
|
||||||
|
public void onItemSelected(int position)
|
||||||
|
{
|
||||||
|
setBucketSizeFromPosition(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onModelChange()
|
||||||
|
{
|
||||||
|
refreshData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHabit(@NonNull Habit habit)
|
||||||
|
{
|
||||||
|
this.habit = habit;
|
||||||
|
color = ColorUtils.getColor(getContext(), habit.getColor());
|
||||||
|
refreshData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onAttachedToWindow()
|
||||||
|
{
|
||||||
|
super.onAttachedToWindow();
|
||||||
|
if (habit != null)
|
||||||
|
{
|
||||||
|
habit.getObservable().addListener(this);
|
||||||
|
habit.getScores().getObservable().addListener(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDetachedFromWindow()
|
||||||
|
{
|
||||||
|
if (habit != null)
|
||||||
|
{
|
||||||
|
habit.getObservable().removeListener(this);
|
||||||
|
habit.getScores().getObservable().removeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
super.onDetachedFromWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private DateUtils.TruncateField getTruncateField()
|
||||||
|
{
|
||||||
|
DateUtils.TruncateField field;
|
||||||
|
|
||||||
|
switch (bucketSize)
|
||||||
|
{
|
||||||
|
case 7:
|
||||||
|
field = DateUtils.TruncateField.WEEK_NUMBER;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 365:
|
||||||
|
field = DateUtils.TruncateField.YEAR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 92:
|
||||||
|
field = DateUtils.TruncateField.QUARTER;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Log.e("ScoreCard",
|
||||||
|
String.format("Unknown bucket size: %d", bucketSize));
|
||||||
|
// continue to case 31
|
||||||
|
|
||||||
|
case 31:
|
||||||
|
field = DateUtils.TruncateField.MONTH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init()
|
||||||
|
{
|
||||||
|
inflate(getContext(), R.layout.show_habit_strength, this);
|
||||||
|
ButterKnife.bind(this);
|
||||||
|
|
||||||
|
int defaultPosition = getDefaultSpinnerPosition();
|
||||||
|
setBucketSizeFromPosition(defaultPosition);
|
||||||
|
spinner.setSelection(defaultPosition);
|
||||||
|
|
||||||
|
if(isInEditMode())
|
||||||
|
{
|
||||||
|
spinner.setVisibility(GONE);
|
||||||
|
title.setTextColor(ColorUtils.getAndroidTestColor(1));
|
||||||
|
chart.setPrimaryColor(ColorUtils.getAndroidTestColor(1));
|
||||||
|
chart.populateWithRandomData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getDefaultSpinnerPosition()
|
||||||
|
{
|
||||||
|
if(isInEditMode()) return 0;
|
||||||
|
return InterfaceUtils.getDefaultScoreSpinnerPosition(getContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshData()
|
||||||
|
{
|
||||||
|
if (habit == null) return;
|
||||||
|
|
||||||
|
title.setTextColor(color);
|
||||||
|
chart.setPrimaryColor(color);
|
||||||
|
|
||||||
|
new BaseTask()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected void doInBackground()
|
||||||
|
{
|
||||||
|
List<Score> scores;
|
||||||
|
|
||||||
|
if (bucketSize == 1) scores = habit.getScores().getAll();
|
||||||
|
else scores = habit.getScores().groupBy(getTruncateField());
|
||||||
|
|
||||||
|
chart.setScores(scores);
|
||||||
|
chart.setBucketSize(bucketSize);
|
||||||
|
}
|
||||||
|
}.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setBucketSizeFromPosition(int position)
|
||||||
|
{
|
||||||
|
if(isInEditMode()) return;
|
||||||
|
|
||||||
|
InterfaceUtils.setDefaultScoreSpinnerPosition(getContext(), position);
|
||||||
|
bucketSize = BUCKET_SIZES[position];
|
||||||
|
refreshData();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,14 +26,12 @@ import android.util.*;
|
|||||||
|
|
||||||
import org.isoron.uhabits.*;
|
import org.isoron.uhabits.*;
|
||||||
import org.isoron.uhabits.models.*;
|
import org.isoron.uhabits.models.*;
|
||||||
import org.isoron.uhabits.tasks.*;
|
|
||||||
import org.isoron.uhabits.utils.*;
|
import org.isoron.uhabits.utils.*;
|
||||||
|
|
||||||
import java.text.*;
|
import java.text.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class HabitScoreView extends ScrollableDataView
|
public class ScoreChart extends ScrollableChart
|
||||||
implements HabitDataView, ModelObservable.Listener
|
|
||||||
{
|
{
|
||||||
private static final PorterDuffXfermode XFERMODE_CLEAR =
|
private static final PorterDuffXfermode XFERMODE_CLEAR =
|
||||||
new PorterDuffXfermode(PorterDuff.Mode.CLEAR);
|
new PorterDuffXfermode(PorterDuff.Mode.CLEAR);
|
||||||
@@ -41,14 +39,10 @@ public class HabitScoreView extends ScrollableDataView
|
|||||||
private static final PorterDuffXfermode XFERMODE_SRC =
|
private static final PorterDuffXfermode XFERMODE_SRC =
|
||||||
new PorterDuffXfermode(PorterDuff.Mode.SRC);
|
new PorterDuffXfermode(PorterDuff.Mode.SRC);
|
||||||
|
|
||||||
public static int DEFAULT_BUCKET_SIZES[] = {1, 7, 31, 92, 365};
|
|
||||||
|
|
||||||
private Paint pGrid;
|
private Paint pGrid;
|
||||||
|
|
||||||
private float em;
|
private float em;
|
||||||
|
|
||||||
private Habit habit;
|
|
||||||
|
|
||||||
private SimpleDateFormat dfMonth;
|
private SimpleDateFormat dfMonth;
|
||||||
|
|
||||||
private SimpleDateFormat dfDay;
|
private SimpleDateFormat dfDay;
|
||||||
@@ -80,8 +74,6 @@ public class HabitScoreView extends ScrollableDataView
|
|||||||
|
|
||||||
private int bucketSize = 7;
|
private int bucketSize = 7;
|
||||||
|
|
||||||
private int footerHeight;
|
|
||||||
|
|
||||||
private int backgroundColor;
|
private int backgroundColor;
|
||||||
|
|
||||||
private Bitmap drawingCache;
|
private Bitmap drawingCache;
|
||||||
@@ -96,51 +88,23 @@ public class HabitScoreView extends ScrollableDataView
|
|||||||
|
|
||||||
private String previousMonthText;
|
private String previousMonthText;
|
||||||
|
|
||||||
public HabitScoreView(Context context)
|
public ScoreChart(Context context)
|
||||||
{
|
{
|
||||||
super(context);
|
super(context);
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public HabitScoreView(Context context, AttributeSet attrs)
|
public ScoreChart(Context context, AttributeSet attrs)
|
||||||
{
|
{
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
this.primaryColor = ColorUtils.getColor(getContext(), 7);
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Deprecated
|
||||||
public void onModelChange()
|
|
||||||
{
|
|
||||||
refreshData();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void refreshData()
|
|
||||||
{
|
|
||||||
if (isInEditMode()) generateRandomData();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (habit == null) return;
|
|
||||||
if (bucketSize == 1) scores = habit.getScores().getAll();
|
|
||||||
else scores = habit.getScores().groupBy(getTruncateField());
|
|
||||||
|
|
||||||
createColors();
|
|
||||||
}
|
|
||||||
|
|
||||||
postInvalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBucketSize(int bucketSize)
|
public void setBucketSize(int bucketSize)
|
||||||
{
|
{
|
||||||
this.bucketSize = bucketSize;
|
this.bucketSize = bucketSize;
|
||||||
}
|
postInvalidate();
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setHabit(Habit habit)
|
|
||||||
{
|
|
||||||
this.habit = habit;
|
|
||||||
createColors();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIsTransparencyEnabled(boolean enabled)
|
public void setIsTransparencyEnabled(boolean enabled)
|
||||||
@@ -150,6 +114,18 @@ public class HabitScoreView extends ScrollableDataView
|
|||||||
requestLayout();
|
requestLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPrimaryColor(int primaryColor)
|
||||||
|
{
|
||||||
|
this.primaryColor = primaryColor;
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScores(@NonNull List<Score> scores)
|
||||||
|
{
|
||||||
|
this.scores = scores;
|
||||||
|
postInvalidate();
|
||||||
|
}
|
||||||
|
|
||||||
protected void createPaints()
|
protected void createPaints()
|
||||||
{
|
{
|
||||||
pText = new Paint();
|
pText = new Paint();
|
||||||
@@ -163,30 +139,6 @@ public class HabitScoreView extends ScrollableDataView
|
|||||||
pGrid.setAntiAlias(true);
|
pGrid.setAntiAlias(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onAttachedToWindow()
|
|
||||||
{
|
|
||||||
super.onAttachedToWindow();
|
|
||||||
new BaseTask()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
protected void doInBackground()
|
|
||||||
{
|
|
||||||
refreshData();
|
|
||||||
}
|
|
||||||
}.execute();
|
|
||||||
habit.getObservable().addListener(this);
|
|
||||||
habit.getScores().getObservable().addListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDetachedFromWindow()
|
|
||||||
{
|
|
||||||
habit.getScores().getObservable().removeListener(this);
|
|
||||||
habit.getObservable().removeListener(this);
|
|
||||||
super.onDetachedFromWindow();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDraw(Canvas canvas)
|
protected void onDraw(Canvas canvas)
|
||||||
{
|
{
|
||||||
@@ -205,7 +157,7 @@ public class HabitScoreView extends ScrollableDataView
|
|||||||
activeCanvas = canvas;
|
activeCanvas = canvas;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (habit == null || scores == null) return;
|
if (scores == null) return;
|
||||||
|
|
||||||
rect.set(0, 0, nColumns * columnWidth, columnHeight);
|
rect.set(0, 0, nColumns * columnWidth, columnHeight);
|
||||||
rect.offset(0, paddingTop);
|
rect.offset(0, paddingTop);
|
||||||
@@ -220,16 +172,13 @@ public class HabitScoreView extends ScrollableDataView
|
|||||||
previousYearText = "";
|
previousYearText = "";
|
||||||
skipYear = 0;
|
skipYear = 0;
|
||||||
|
|
||||||
long currentDate = DateUtils.getStartOfToday();
|
|
||||||
|
|
||||||
for (int k = 0; k < nColumns + getDataOffset() - 1; k++)
|
|
||||||
currentDate -= bucketSize * DateUtils.millisecondsInOneDay;
|
|
||||||
|
|
||||||
for (int k = 0; k < nColumns; k++)
|
for (int k = 0; k < nColumns; k++)
|
||||||
{
|
{
|
||||||
int score = 0;
|
|
||||||
int offset = nColumns - k - 1 + getDataOffset();
|
int offset = nColumns - k - 1 + getDataOffset();
|
||||||
if (offset < scores.size()) score = scores.get(offset).getValue();
|
if (offset >= scores.size()) continue;
|
||||||
|
|
||||||
|
int score = scores.get(offset).getValue();
|
||||||
|
long timestamp = scores.get(offset).getTimestamp();
|
||||||
|
|
||||||
double relativeScore = ((double) score) / Score.MAX_VALUE;
|
double relativeScore = ((double) score) / Score.MAX_VALUE;
|
||||||
int height = (int) (columnHeight * relativeScore);
|
int height = (int) (columnHeight * relativeScore);
|
||||||
@@ -250,9 +199,7 @@ public class HabitScoreView extends ScrollableDataView
|
|||||||
rect.set(0, 0, columnWidth, columnHeight);
|
rect.set(0, 0, columnWidth, columnHeight);
|
||||||
rect.offset(k * columnWidth, paddingTop);
|
rect.offset(k * columnWidth, paddingTop);
|
||||||
|
|
||||||
drawFooter(activeCanvas, rect, currentDate);
|
drawFooter(activeCanvas, rect, timestamp);
|
||||||
|
|
||||||
currentDate += bucketSize * DateUtils.millisecondsInOneDay;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeCanvas != canvas) canvas.drawBitmap(drawingCache, 0, 0, null);
|
if (activeCanvas != canvas) canvas.drawBitmap(drawingCache, 0, 0, null);
|
||||||
@@ -279,18 +226,17 @@ public class HabitScoreView extends ScrollableDataView
|
|||||||
pText.setTextSize(Math.min(textSize, maxTextSize));
|
pText.setTextSize(Math.min(textSize, maxTextSize));
|
||||||
em = pText.getFontSpacing();
|
em = pText.getFontSpacing();
|
||||||
|
|
||||||
footerHeight = (int) (3 * em);
|
int footerHeight = (int) (3 * em);
|
||||||
paddingTop = (int) (em);
|
paddingTop = (int) (em);
|
||||||
|
|
||||||
baseSize = (height - footerHeight - paddingTop) / 8;
|
baseSize = (height - footerHeight - paddingTop) / 8;
|
||||||
setScrollerBucketSize(baseSize);
|
|
||||||
|
|
||||||
columnWidth = baseSize;
|
columnWidth = baseSize;
|
||||||
columnWidth = Math.max(columnWidth, getMaxDayWidth() * 1.5f);
|
columnWidth = Math.max(columnWidth, getMaxDayWidth() * 1.5f);
|
||||||
columnWidth = Math.max(columnWidth, getMaxMonthWidth() * 1.2f);
|
columnWidth = Math.max(columnWidth, getMaxMonthWidth() * 1.2f);
|
||||||
|
|
||||||
nColumns = (int) (width / columnWidth);
|
nColumns = (int) (width / columnWidth);
|
||||||
columnWidth = (float) width / nColumns;
|
columnWidth = (float) width / nColumns;
|
||||||
|
setScrollerBucketSize((int) columnWidth);
|
||||||
|
|
||||||
columnHeight = 8 * baseSize;
|
columnHeight = 8 * baseSize;
|
||||||
|
|
||||||
@@ -304,9 +250,7 @@ public class HabitScoreView extends ScrollableDataView
|
|||||||
|
|
||||||
private void createColors()
|
private void createColors()
|
||||||
{
|
{
|
||||||
if (habit != null) this.primaryColor =
|
primaryColor = Color.BLACK;
|
||||||
ColorUtils.getColor(getContext(), habit.getColor());
|
|
||||||
|
|
||||||
textColor = InterfaceUtils.getStyledColor(getContext(),
|
textColor = InterfaceUtils.getStyledColor(getContext(),
|
||||||
R.attr.mediumContrastTextColor);
|
R.attr.mediumContrastTextColor);
|
||||||
gridColor = InterfaceUtils.getStyledColor(getContext(),
|
gridColor = InterfaceUtils.getStyledColor(getContext(),
|
||||||
@@ -411,7 +355,7 @@ public class HabitScoreView extends ScrollableDataView
|
|||||||
if (isTransparencyEnabled) pGraph.setXfermode(XFERMODE_SRC);
|
if (isTransparencyEnabled) pGraph.setXfermode(XFERMODE_SRC);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateRandomData()
|
public void populateWithRandomData()
|
||||||
{
|
{
|
||||||
Random random = new Random();
|
Random random = new Random();
|
||||||
scores = new LinkedList<>();
|
scores = new LinkedList<>();
|
||||||
@@ -461,38 +405,6 @@ public class HabitScoreView extends ScrollableDataView
|
|||||||
return maxMonthWidth;
|
return maxMonthWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private DateUtils.TruncateField getTruncateField()
|
|
||||||
{
|
|
||||||
DateUtils.TruncateField field;
|
|
||||||
|
|
||||||
switch (bucketSize)
|
|
||||||
{
|
|
||||||
case 7:
|
|
||||||
field = DateUtils.TruncateField.WEEK_NUMBER;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 365:
|
|
||||||
field = DateUtils.TruncateField.YEAR;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 92:
|
|
||||||
field = DateUtils.TruncateField.QUARTER;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
Log.e("HabitScoreView",
|
|
||||||
String.format("Unknown bucket size: %d", bucketSize));
|
|
||||||
// continue to case 31
|
|
||||||
|
|
||||||
case 31:
|
|
||||||
field = DateUtils.TruncateField.MONTH;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return field;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init()
|
private void init()
|
||||||
{
|
{
|
||||||
createPaints();
|
createPaints();
|
||||||
@@ -25,7 +25,7 @@ import android.util.*;
|
|||||||
import android.view.*;
|
import android.view.*;
|
||||||
import android.widget.*;
|
import android.widget.*;
|
||||||
|
|
||||||
public abstract class ScrollableDataView extends View
|
public abstract class ScrollableChart extends View
|
||||||
implements GestureDetector.OnGestureListener,
|
implements GestureDetector.OnGestureListener,
|
||||||
ValueAnimator.AnimatorUpdateListener
|
ValueAnimator.AnimatorUpdateListener
|
||||||
{
|
{
|
||||||
@@ -40,13 +40,13 @@ public abstract class ScrollableDataView extends View
|
|||||||
|
|
||||||
private ValueAnimator scrollAnimator;
|
private ValueAnimator scrollAnimator;
|
||||||
|
|
||||||
public ScrollableDataView(Context context)
|
public ScrollableChart(Context context)
|
||||||
{
|
{
|
||||||
super(context);
|
super(context);
|
||||||
init(context);
|
init(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScrollableDataView(Context context, AttributeSet attrs)
|
public ScrollableChart(Context context, AttributeSet attrs)
|
||||||
{
|
{
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
init(context);
|
init(context);
|
||||||
@@ -32,7 +32,7 @@ import org.isoron.uhabits.utils.*;
|
|||||||
import java.text.*;
|
import java.text.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class HabitStreakView extends View
|
public class StreakChart extends View
|
||||||
implements HabitDataView, ModelObservable.Listener
|
implements HabitDataView, ModelObservable.Listener
|
||||||
{
|
{
|
||||||
private Habit habit;
|
private Habit habit;
|
||||||
@@ -73,13 +73,13 @@ public class HabitStreakView extends View
|
|||||||
|
|
||||||
private int reverseTextColor;
|
private int reverseTextColor;
|
||||||
|
|
||||||
public HabitStreakView(Context context)
|
public StreakChart(Context context)
|
||||||
{
|
{
|
||||||
super(context);
|
super(context);
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public HabitStreakView(Context context, AttributeSet attrs)
|
public StreakChart(Context context, AttributeSet attrs)
|
||||||
{
|
{
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
this.primaryColor = ColorUtils.getColor(getContext(), 7);
|
this.primaryColor = ColorUtils.getColor(getContext(), 7);
|
||||||
@@ -33,7 +33,7 @@ import org.isoron.uhabits.utils.*;
|
|||||||
|
|
||||||
import butterknife.*;
|
import butterknife.*;
|
||||||
|
|
||||||
public class SubtitleCardView extends LinearLayout
|
public class SubtitleCard extends LinearLayout
|
||||||
implements ModelObservable.Listener
|
implements ModelObservable.Listener
|
||||||
{
|
{
|
||||||
@BindView(R.id.questionLabel)
|
@BindView(R.id.questionLabel)
|
||||||
@@ -48,13 +48,13 @@ public class SubtitleCardView extends LinearLayout
|
|||||||
@Nullable
|
@Nullable
|
||||||
private Habit habit;
|
private Habit habit;
|
||||||
|
|
||||||
public SubtitleCardView(Context context)
|
public SubtitleCard(Context context)
|
||||||
{
|
{
|
||||||
super(context);
|
super(context);
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public SubtitleCardView(Context context, AttributeSet attrs)
|
public SubtitleCard(Context context, AttributeSet attrs)
|
||||||
{
|
{
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
init();
|
init();
|
||||||
@@ -269,13 +269,13 @@ public abstract class InterfaceUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void setDefaultScoreInterval(Context context, int position)
|
public static void setDefaultScoreSpinnerPosition(Context context, int position)
|
||||||
{
|
{
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
prefs.edit().putInt("pref_score_view_interval", position).apply();
|
prefs.edit().putInt("pref_score_view_interval", position).apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getDefaultScoreInterval(Context context)
|
public static int getDefaultScoreSpinnerPosition(Context context)
|
||||||
{
|
{
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
int defaultScoreInterval = prefs.getInt("pref_score_view_interval", 1);
|
int defaultScoreInterval = prefs.getInt("pref_score_view_interval", 1);
|
||||||
|
|||||||
@@ -28,14 +28,14 @@ import org.isoron.uhabits.R;
|
|||||||
import org.isoron.uhabits.models.Habit;
|
import org.isoron.uhabits.models.Habit;
|
||||||
import org.isoron.uhabits.widgets.views.GraphWidgetView;
|
import org.isoron.uhabits.widgets.views.GraphWidgetView;
|
||||||
import org.isoron.uhabits.ui.habits.show.views.HabitDataView;
|
import org.isoron.uhabits.ui.habits.show.views.HabitDataView;
|
||||||
import org.isoron.uhabits.ui.habits.show.views.HabitFrequencyView;
|
import org.isoron.uhabits.ui.habits.show.views.FrequencyChart;
|
||||||
|
|
||||||
public class FrequencyWidgetProvider extends BaseWidgetProvider
|
public class FrequencyWidgetProvider extends BaseWidgetProvider
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
protected View buildCustomView(Context context, Habit habit)
|
protected View buildCustomView(Context context, Habit habit)
|
||||||
{
|
{
|
||||||
HabitFrequencyView dataView = new HabitFrequencyView(context);
|
FrequencyChart dataView = new FrequencyChart(context);
|
||||||
GraphWidgetView view = new GraphWidgetView(context, dataView);
|
GraphWidgetView view = new GraphWidgetView(context, dataView);
|
||||||
view.setHabit(habit);
|
view.setHabit(habit);
|
||||||
return view;
|
return view;
|
||||||
|
|||||||
@@ -27,14 +27,14 @@ import org.isoron.uhabits.R;
|
|||||||
import org.isoron.uhabits.models.Habit;
|
import org.isoron.uhabits.models.Habit;
|
||||||
import org.isoron.uhabits.widgets.views.GraphWidgetView;
|
import org.isoron.uhabits.widgets.views.GraphWidgetView;
|
||||||
import org.isoron.uhabits.ui.habits.show.views.HabitDataView;
|
import org.isoron.uhabits.ui.habits.show.views.HabitDataView;
|
||||||
import org.isoron.uhabits.ui.habits.show.views.HabitHistoryView;
|
import org.isoron.uhabits.ui.habits.show.views.HistoryView;
|
||||||
|
|
||||||
public class HistoryWidgetProvider extends BaseWidgetProvider
|
public class HistoryWidgetProvider extends BaseWidgetProvider
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
protected View buildCustomView(Context context, Habit habit)
|
protected View buildCustomView(Context context, Habit habit)
|
||||||
{
|
{
|
||||||
HabitHistoryView dataView = new HabitHistoryView(context);
|
HistoryView dataView = new HistoryView(context);
|
||||||
GraphWidgetView view = new GraphWidgetView(context, dataView);
|
GraphWidgetView view = new GraphWidgetView(context, dataView);
|
||||||
view.setHabit(habit);
|
view.setHabit(habit);
|
||||||
return view;
|
return view;
|
||||||
|
|||||||
@@ -18,33 +18,33 @@
|
|||||||
*/
|
*/
|
||||||
package org.isoron.uhabits.widgets;
|
package org.isoron.uhabits.widgets;
|
||||||
|
|
||||||
import android.app.PendingIntent;
|
import android.app.*;
|
||||||
import android.content.Context;
|
import android.content.*;
|
||||||
import android.view.View;
|
import android.view.*;
|
||||||
|
|
||||||
import org.isoron.uhabits.HabitBroadcastReceiver;
|
import org.apache.commons.lang3.*;
|
||||||
import org.isoron.uhabits.R;
|
import org.isoron.uhabits.*;
|
||||||
import org.isoron.uhabits.models.Habit;
|
import org.isoron.uhabits.models.*;
|
||||||
import org.isoron.uhabits.utils.InterfaceUtils;
|
import org.isoron.uhabits.ui.habits.show.views.*;
|
||||||
import org.isoron.uhabits.widgets.views.GraphWidgetView;
|
import org.isoron.uhabits.utils.*;
|
||||||
import org.isoron.uhabits.ui.habits.show.views.HabitDataView;
|
|
||||||
import org.isoron.uhabits.ui.habits.show.views.HabitScoreView;
|
|
||||||
|
|
||||||
public class ScoreWidgetProvider extends BaseWidgetProvider
|
public class ScoreWidgetProvider extends BaseWidgetProvider
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
protected View buildCustomView(Context context, Habit habit)
|
protected View buildCustomView(Context context, Habit habit)
|
||||||
{
|
{
|
||||||
int defaultScoreInterval = InterfaceUtils.getDefaultScoreInterval(context);
|
int defaultScoreInterval = InterfaceUtils.getDefaultScoreSpinnerPosition(context);
|
||||||
int size = HabitScoreView.DEFAULT_BUCKET_SIZES[defaultScoreInterval];
|
int size = ScoreCard.BUCKET_SIZES[defaultScoreInterval];
|
||||||
|
|
||||||
HabitScoreView dataView = new HabitScoreView(context);
|
ScoreChart dataView = new ScoreChart(context);
|
||||||
dataView.setIsTransparencyEnabled(true);
|
dataView.setIsTransparencyEnabled(true);
|
||||||
dataView.setBucketSize(size);
|
dataView.setBucketSize(size);
|
||||||
|
|
||||||
GraphWidgetView view = new GraphWidgetView(context, dataView);
|
// GraphWidgetView view = new GraphWidgetView(context, dataView);
|
||||||
view.setHabit(habit);
|
// view.setHabit(habit);
|
||||||
return view;
|
// return view;
|
||||||
|
|
||||||
|
throw new NotImplementedException("");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -27,14 +27,14 @@ import org.isoron.uhabits.R;
|
|||||||
import org.isoron.uhabits.models.Habit;
|
import org.isoron.uhabits.models.Habit;
|
||||||
import org.isoron.uhabits.widgets.views.GraphWidgetView;
|
import org.isoron.uhabits.widgets.views.GraphWidgetView;
|
||||||
import org.isoron.uhabits.ui.habits.show.views.HabitDataView;
|
import org.isoron.uhabits.ui.habits.show.views.HabitDataView;
|
||||||
import org.isoron.uhabits.ui.habits.show.views.HabitStreakView;
|
import org.isoron.uhabits.ui.habits.show.views.StreakChart;
|
||||||
|
|
||||||
public class StreakWidgetProvider extends BaseWidgetProvider
|
public class StreakWidgetProvider extends BaseWidgetProvider
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
protected View buildCustomView(Context context, Habit habit)
|
protected View buildCustomView(Context context, Habit habit)
|
||||||
{
|
{
|
||||||
HabitStreakView dataView = new HabitStreakView(context);
|
StreakChart dataView = new StreakChart(context);
|
||||||
GraphWidgetView view = new GraphWidgetView(context, dataView);
|
GraphWidgetView view = new GraphWidgetView(context, dataView);
|
||||||
view.setHabit(habit);
|
view.setHabit(habit);
|
||||||
return view;
|
return view;
|
||||||
|
|||||||
@@ -31,49 +31,23 @@
|
|||||||
style="@style/CardList"
|
style="@style/CardList"
|
||||||
android:clipToPadding="false">
|
android:clipToPadding="false">
|
||||||
|
|
||||||
<org.isoron.uhabits.ui.habits.show.views.SubtitleCardView
|
<org.isoron.uhabits.ui.habits.show.views.SubtitleCard
|
||||||
style="@style/ShowHabit.Subtitle"
|
style="@style/ShowHabit.Subtitle"
|
||||||
android:id="@+id/subtitle"/>
|
android:id="@+id/subtitleCard"/>
|
||||||
|
|
||||||
<!--<View-->
|
<!--<View-->
|
||||||
<!--android:id="@+id/headerShadow"-->
|
<!--android:id="@+id/headerShadow"-->
|
||||||
<!--style="@style/ToolbarShadow"/>-->
|
<!--style="@style/ToolbarShadow"/>-->
|
||||||
|
|
||||||
<org.isoron.uhabits.ui.habits.show.views.OverviewCardView
|
<org.isoron.uhabits.ui.habits.show.views.OverviewCard
|
||||||
android:id="@+id/overview"
|
android:id="@+id/overviewCard"
|
||||||
android:paddingTop="12dp"
|
android:paddingTop="12dp"
|
||||||
style="@style/Card" />
|
style="@style/Card" />
|
||||||
|
|
||||||
<RelativeLayout
|
<org.isoron.uhabits.ui.habits.show.views.ScoreCard
|
||||||
|
android:id="@+id/strengthCard"
|
||||||
style="@style/Card"
|
style="@style/Card"
|
||||||
android:gravity="center">
|
android:gravity="center" />
|
||||||
|
|
||||||
<android.support.v7.widget.AppCompatSpinner
|
|
||||||
android:id="@+id/sStrengthInterval"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="22dp"
|
|
||||||
android:layout_alignParentEnd="true"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_alignParentTop="true"
|
|
||||||
android:entries="@array/strengthIntervalNames"
|
|
||||||
android:theme="@style/SmallSpinner"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/tvStrength"
|
|
||||||
style="@style/CardHeader"
|
|
||||||
android:layout_alignParentLeft="true"
|
|
||||||
android:layout_alignParentStart="true"
|
|
||||||
android:layout_alignParentTop="true"
|
|
||||||
android:text="@string/habit_strength"/>
|
|
||||||
|
|
||||||
<org.isoron.uhabits.ui.habits.show.views.HabitScoreView
|
|
||||||
android:id="@+id/scoreView"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="220dp"
|
|
||||||
android:layout_below="@id/tvStrength"/>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
style="@style/Card"
|
style="@style/Card"
|
||||||
@@ -86,7 +60,7 @@
|
|||||||
style="@style/CardHeader"
|
style="@style/CardHeader"
|
||||||
android:text="@string/history"/>
|
android:text="@string/history"/>
|
||||||
|
|
||||||
<org.isoron.uhabits.ui.habits.show.views.HabitHistoryView
|
<org.isoron.uhabits.ui.habits.show.views.HistoryView
|
||||||
android:id="@+id/historyView"
|
android:id="@+id/historyView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="160dp"/>
|
android:layout_height="160dp"/>
|
||||||
@@ -113,8 +87,8 @@
|
|||||||
style="@style/CardHeader"
|
style="@style/CardHeader"
|
||||||
android:text="@string/best_streaks"/>
|
android:text="@string/best_streaks"/>
|
||||||
|
|
||||||
<org.isoron.uhabits.ui.habits.show.views.HabitStreakView
|
<org.isoron.uhabits.ui.habits.show.views.StreakChart
|
||||||
android:id="@+id/streakView"
|
android:id="@+id/streakChart"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="200dp"/>
|
android:layout_height="200dp"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -128,7 +102,7 @@
|
|||||||
style="@style/CardHeader"
|
style="@style/CardHeader"
|
||||||
android:text="@string/frequency"/>
|
android:text="@string/frequency"/>
|
||||||
|
|
||||||
<org.isoron.uhabits.ui.habits.show.views.HabitFrequencyView
|
<org.isoron.uhabits.ui.habits.show.views.FrequencyChart
|
||||||
android:id="@+id/punchcardView"
|
android:id="@+id/punchcardView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="200dp"/>
|
android:layout_height="200dp"/>
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="?windowBackgroundColor"
|
android:background="?windowBackgroundColor"
|
||||||
@@ -31,24 +30,28 @@
|
|||||||
<android.support.v7.widget.Toolbar
|
<android.support.v7.widget.Toolbar
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
style="@style/Toolbar"
|
style="@style/Toolbar"
|
||||||
app:title="Meditation"
|
|
||||||
android:background="@color/deep_orange_700"
|
android:background="@color/deep_orange_700"
|
||||||
|
android:elevation="1dp"
|
||||||
app:popupTheme="?toolbarPopupTheme"
|
app:popupTheme="?toolbarPopupTheme"
|
||||||
android:elevation="1dp"/>
|
app:title="Meditation"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
style="@style/CardList"
|
style="@style/CardList"
|
||||||
android:clipToPadding="false">
|
android:clipToPadding="false">
|
||||||
|
|
||||||
<org.isoron.uhabits.ui.habits.show.views.SubtitleCardView
|
<org.isoron.uhabits.ui.habits.show.views.SubtitleCard
|
||||||
android:id="@+id/subtitleView"
|
android:id="@+id/subtitleView"
|
||||||
style="@style/ShowHabit.Subtitle"
|
style="@style/ShowHabit.Subtitle"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"/>
|
android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
<org.isoron.uhabits.ui.habits.show.views.OverviewCardView
|
<org.isoron.uhabits.ui.habits.show.views.OverviewCard
|
||||||
android:paddingTop="12dp"
|
style="@style/Card"
|
||||||
style="@style/Card" />
|
android:paddingTop="12dp"/>
|
||||||
|
|
||||||
|
<org.isoron.uhabits.ui.habits.show.views.ScoreCard
|
||||||
|
style="@style/Card"
|
||||||
|
android:paddingTop="12dp"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
48
app/src/main/res/layout/show_habit_strength.xml
Normal file
48
app/src/main/res/layout/show_habit_strength.xml
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright (C) 2016 Álinson Santos Xavier <isoron@gmail.com>
|
||||||
|
~
|
||||||
|
~ This file is part of Loop Habit Tracker.
|
||||||
|
~
|
||||||
|
~ Loop Habit Tracker 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.
|
||||||
|
~
|
||||||
|
~ Loop Habit Tracker 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/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<android.support.v7.widget.AppCompatSpinner
|
||||||
|
android:id="@+id/spinner"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="22dp"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:entries="@array/strengthIntervalNames"
|
||||||
|
android:theme="@style/SmallSpinner"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
style="@style/CardHeader"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:text="@string/habit_strength"/>
|
||||||
|
|
||||||
|
<org.isoron.uhabits.ui.habits.show.views.ScoreChart
|
||||||
|
android:id="@+id/scoreView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="220dp"
|
||||||
|
android:layout_below="@id/title"/>
|
||||||
|
|
||||||
|
</merge>
|
||||||
Reference in New Issue
Block a user