Implement NumberButtonView and related classes

pull/157/merge
Alinson S. Xavier 9 years ago
parent 19e79a8559
commit 7bf9f88ee3

@ -91,97 +91,4 @@ public class CheckmarkButtonViewTest extends BaseViewTest
{ {
assertRenders(view, PATH + "render_unchecked.png"); assertRenders(view, PATH + "render_unchecked.png");
} }
// @Test
// public void testLongClick() throws Exception
// {
// setOnToggleListener();
// view.performLongClick();
// waitForLatch();
// assertRendersCheckedExplicitly();
// }
//
// @Test
// public void testClick_withShortToggle_fromUnchecked() throws Exception
// {
// Preferences.getInstance().setShortToggleEnabled(true);
// view.setValue(Checkmark.UNCHECKED);
// setOnToggleListenerAndPerformClick();
// assertRendersCheckedExplicitly();
// }
//
// @Test
// public void testClick_withShortToggle_fromChecked() throws Exception
// {
// Preferences.getInstance().setShortToggleEnabled(true);
// view.setValue(Checkmark.CHECKED_EXPLICITLY);
// setOnToggleListenerAndPerformClick();
// assertRendersUnchecked();
// }
//
// @Test
// public void testClick_withShortToggle_withoutListener() throws Exception
// {
// Preferences.getInstance().setShortToggleEnabled(true);
// view.setValue(Checkmark.CHECKED_EXPLICITLY);
// view.setController(null);
// view.performClick();
// assertRendersUnchecked();
// }
//
// protected void setOnToggleListenerAndPerformClick() throws InterruptedException
// {
// setOnToggleListener();
// view.performClick();
// waitForLatch();
// }
//
// @Test
// public void testClick_withoutShortToggle() throws Exception
// {
// Preferences.getInstance().setShortToggleEnabled(false);
// setOnInvalidToggleListener();
// view.performClick();
// waitForLatch();
// assertRendersUnchecked();
// }
// protected void setOnInvalidToggleListener()
// {
// view.setController(new CheckmarkButtonView.Controller()
// {
// @Override
// public void onToggleCheckmark(CheckmarkButtonView view, long timestamp)
// {
// fail();
// }
//
// @Override
// public void onInvalidToggle(CheckmarkButtonView v)
// {
// assertThat(v, equalTo(view));
// latch.countDown();
// }
// });
// }
// protected void setOnToggleListener()
// {
// view.setController(new CheckmarkButtonView.Controller()
// {
// @Override
// public void onToggleCheckmark(CheckmarkButtonView v, long t)
// {
// assertThat(v, equalTo(view));
// assertThat(t, equalTo(DateUtils.getStartOfToday()));
// latch.countDown();
// }
//
// @Override
// public void onInvalidToggle(CheckmarkButtonView view)
// {
// fail();
// }
// });
// }
} }

@ -59,7 +59,7 @@ public class CheckmarkPanelViewTest extends BaseViewTest
view = new CheckmarkPanelView(targetContext); view = new CheckmarkPanelView(targetContext);
view.setHabit(habit); view.setHabit(habit);
view.setCheckmarkValues(checkmarks); view.setValues(checkmarks);
view.setButtonCount(4); view.setButtonCount(4);
view.setColor(ColorUtils.getAndroidTestColor(7)); view.setColor(ColorUtils.getAndroidTestColor(7));

@ -32,19 +32,21 @@ import dagger.*;
dependencies = { AppComponent.class }) dependencies = { AppComponent.class })
public interface ListHabitsComponent public interface ListHabitsComponent
{ {
CheckmarkButtonControllerFactory getCheckmarkButtonControllerFactory();
HabitCardListAdapter getAdapter(); HabitCardListAdapter getAdapter();
CheckmarkButtonControllerFactory getCheckmarkButtonControllerFactory();
ListHabitsController getController(); ListHabitsController getController();
ListHabitsMenu getMenu(); ListHabitsMenu getMenu();
MidnightTimer getMidnightTimer();
NumberButtonControllerFactory getNumberButtonControllerFactory();
ListHabitsRootView getRootView(); ListHabitsRootView getRootView();
ListHabitsScreen getScreen(); ListHabitsScreen getScreen();
ListHabitsSelectionMenu getSelectionMenu(); ListHabitsSelectionMenu getSelectionMenu();
MidnightTimer getMidnightTimer();
} }

@ -0,0 +1,102 @@
/*
* 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.activities.habits.list.controllers;
import android.support.annotation.*;
import com.google.auto.factory.*;
import org.isoron.uhabits.activities.habits.list.views.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.preferences.*;
@AutoFactory
public class NumberButtonController
{
@Nullable
private NumberButtonView view;
@Nullable
private Listener listener;
@NonNull
private final Preferences prefs;
@NonNull
private Habit habit;
private long timestamp;
public NumberButtonController(@Provided @NonNull Preferences prefs,
@NonNull Habit habit,
long timestamp)
{
this.habit = habit;
this.timestamp = timestamp;
this.prefs = prefs;
}
public void onClick()
{
if (prefs.isShortToggleEnabled()) performEdit();
else performInvalidToggle();
}
public boolean onLongClick()
{
performEdit();
return true;
}
public void performInvalidToggle()
{
if (listener != null) listener.onInvalidEdit();
}
public void performEdit()
{
if (listener != null) listener.onEdit(habit, timestamp);
}
public void setListener(@Nullable Listener listener)
{
this.listener = listener;
}
public void setView(@Nullable NumberButtonView view)
{
this.view = view;
}
public interface Listener
{
/**
* Called when the user's attempt to edit the value is rejected.
*/
void onInvalidEdit();
/**
* Called when a the user's attempt to edit the value has been accepted.
* @param habit the habit being edited
* @param timestamp the timestamp being edited
*/
void onEdit(@NonNull Habit habit, long timestamp);
}
}

@ -20,6 +20,8 @@
package org.isoron.uhabits.activities.habits.list.views; package org.isoron.uhabits.activities.habits.list.views;
import android.content.*; import android.content.*;
import android.support.annotation.*;
import android.util.*;
import android.view.*; import android.view.*;
import android.widget.*; import android.widget.*;
@ -28,6 +30,9 @@ import org.isoron.uhabits.activities.habits.list.controllers.*;
import org.isoron.uhabits.models.*; import org.isoron.uhabits.models.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
import static org.isoron.uhabits.utils.AttributeSetUtils.*;
import static org.isoron.uhabits.utils.ColorUtils.*;
public class CheckmarkButtonView extends TextView public class CheckmarkButtonView extends TextView
{ {
private int color; private int color;
@ -36,16 +41,31 @@ public class CheckmarkButtonView extends TextView
private StyledResources res; private StyledResources res;
public CheckmarkButtonView(Context context) public CheckmarkButtonView(@Nullable Context context)
{ {
super(context); super(context);
init(); init();
} }
public CheckmarkButtonView(@Nullable Context context,
@Nullable AttributeSet attrs)
{
super(context, attrs);
init();
if (context != null && attrs != null)
{
int color = getIntAttribute(context, attrs, "color", 0);
int value = getIntAttribute(context, attrs, "value", 0);
setColor(getAndroidTestColor(color));
setValue(value);
}
}
public void setColor(int color) public void setColor(int color)
{ {
this.color = color; this.color = color;
postInvalidate(); updateText();
} }
public void setController(final CheckmarkButtonController controller) public void setController(final CheckmarkButtonController controller)

@ -31,18 +31,23 @@ import org.isoron.uhabits.models.*;
import org.isoron.uhabits.preferences.*; import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.utils.*; import org.isoron.uhabits.utils.*;
import java.util.*;
import static android.view.View.MeasureSpec.*; import static android.view.View.MeasureSpec.*;
import static org.isoron.uhabits.utils.AttributeSetUtils.*;
import static org.isoron.uhabits.utils.ColorUtils.*;
public class CheckmarkPanelView extends LinearLayout implements Preferences.Listener public class CheckmarkPanelView extends LinearLayout
implements Preferences.Listener
{ {
private static final int CHECKMARK_LEFT_TO_RIGHT = 0; private static final int LEFT_TO_RIGHT = 0;
private static final int CHECKMARK_RIGHT_TO_LEFT = 1; private static final int RIGHT_TO_LEFT = 1;
@Nullable @Nullable
private Preferences prefs; private Preferences prefs;
private int checkmarkValues[]; private int values[];
private int nButtons; private int nButtons;
@ -61,61 +66,89 @@ public class CheckmarkPanelView extends LinearLayout implements Preferences.List
init(); init();
} }
public CheckmarkPanelView(Context context, AttributeSet attrs) public CheckmarkPanelView(Context ctx, AttributeSet attrs)
{ {
super(context, attrs); super(ctx, attrs);
init(); init();
if (ctx != null && attrs != null)
{
int paletteColor = getIntAttribute(ctx, attrs, "color", 0);
setColor(getAndroidTestColor(paletteColor));
setButtonCount(getIntAttribute(ctx, attrs, "button_count", 5));
}
if (isInEditMode()) initEditMode();
} }
public CheckmarkButtonView indexToButton(int i) public CheckmarkButtonView indexToButton(int i)
{ {
int position = i; int position = i;
if (getCheckmarkOrder() == CHECKMARK_RIGHT_TO_LEFT) if (getCheckmarkOrder() == RIGHT_TO_LEFT) position = nButtons - i - 1;
position = nButtons - i - 1;
return (CheckmarkButtonView) getChildAt(position); return (CheckmarkButtonView) getChildAt(position);
} }
@Override
public void onCheckmarkOrderChanged()
{
setupButtons();
}
public void setButtonCount(int newButtonCount) public void setButtonCount(int newButtonCount)
{ {
if (nButtons != newButtonCount) if (nButtons != newButtonCount)
{ {
nButtons = newButtonCount; nButtons = newButtonCount;
addCheckmarkButtons(); addButtons();
} }
setupCheckmarkButtons(); setupButtons();
}
public void setCheckmarkValues(int[] checkmarkValues)
{
this.checkmarkValues = checkmarkValues;
setupCheckmarkButtons();
} }
public void setColor(int color) public void setColor(int color)
{ {
this.color = color; this.color = color;
setupCheckmarkButtons(); setupButtons();
} }
public void setController(Controller controller) public void setController(Controller controller)
{ {
this.controller = controller; this.controller = controller;
setupCheckmarkButtons(); setupButtons();
} }
public void setDataOffset(int dataOffset) public void setDataOffset(int dataOffset)
{ {
this.dataOffset = dataOffset; this.dataOffset = dataOffset;
setupCheckmarkButtons(); setupButtons();
} }
public void setHabit(@NonNull Habit habit) public void setHabit(@NonNull Habit habit)
{ {
this.habit = habit; this.habit = habit;
setupCheckmarkButtons(); setupButtons();
}
public void setValues(int[] values)
{
this.values = values;
setupButtons();
}
@Override
protected void onAttachedToWindow()
{
super.onAttachedToWindow();
if (prefs != null) prefs.addListener(this);
}
@Override
protected void onDetachedFromWindow()
{
if (prefs != null) prefs.removeListener(this);
super.onDetachedFromWindow();
} }
@Override @Override
@ -133,7 +166,7 @@ public class CheckmarkPanelView extends LinearLayout implements Preferences.List
super.onMeasure(widthSpec, heightSpec); super.onMeasure(widthSpec, heightSpec);
} }
private void addCheckmarkButtons() private void addButtons()
{ {
removeAllViews(); removeAllViews();
@ -143,9 +176,8 @@ public class CheckmarkPanelView extends LinearLayout implements Preferences.List
private int getCheckmarkOrder() private int getCheckmarkOrder()
{ {
if (prefs == null) return CHECKMARK_LEFT_TO_RIGHT; if (prefs == null) return LEFT_TO_RIGHT;
return prefs.shouldReverseCheckmarks() ? CHECKMARK_RIGHT_TO_LEFT : return prefs.shouldReverseCheckmarks() ? RIGHT_TO_LEFT : LEFT_TO_RIGHT;
CHECKMARK_LEFT_TO_RIGHT;
} }
private void init() private void init()
@ -158,6 +190,17 @@ public class CheckmarkPanelView extends LinearLayout implements Preferences.List
} }
setWillNotDraw(false); setWillNotDraw(false);
values = new int[0];
}
private void initEditMode()
{
int values[] = new int[nButtons];
for (int i = 0; i < nButtons; i++)
values[i] = new Random().nextInt(3);
setValues(values);
} }
private void setupButtonControllers(long timestamp, private void setupButtonControllers(long timestamp,
@ -178,7 +221,7 @@ public class CheckmarkPanelView extends LinearLayout implements Preferences.List
buttonView.setController(buttonController); buttonView.setController(buttonController);
} }
private void setupCheckmarkButtons() private void setupButtons()
{ {
long timestamp = DateUtils.getStartOfToday(); long timestamp = DateUtils.getStartOfToday();
long day = DateUtils.millisecondsInOneDay; long day = DateUtils.millisecondsInOneDay;
@ -187,34 +230,14 @@ public class CheckmarkPanelView extends LinearLayout implements Preferences.List
for (int i = 0; i < nButtons; i++) for (int i = 0; i < nButtons; i++)
{ {
CheckmarkButtonView buttonView = indexToButton(i); CheckmarkButtonView buttonView = indexToButton(i);
if(i + dataOffset >= checkmarkValues.length) break; if (i + dataOffset >= values.length) break;
buttonView.setValue(checkmarkValues[i + dataOffset]); buttonView.setValue(values[i + dataOffset]);
buttonView.setColor(color); buttonView.setColor(color);
setupButtonControllers(timestamp, buttonView); setupButtonControllers(timestamp, buttonView);
timestamp -= day; timestamp -= day;
} }
} }
@Override
protected void onAttachedToWindow()
{
super.onAttachedToWindow();
if(prefs != null) prefs.addListener(this);
}
@Override
protected void onDetachedFromWindow()
{
if(prefs != null) prefs.removeListener(this);
super.onDetachedFromWindow();
}
@Override
public void onCheckmarkOrderChanged()
{
setupCheckmarkButtons();
}
public interface Controller extends CheckmarkButtonController.Listener public interface Controller extends CheckmarkButtonController.Listener
{ {

@ -99,7 +99,7 @@ public class HabitCardView extends FrameLayout
public void setCheckmarkValues(int checkmarks[]) public void setCheckmarkValues(int checkmarks[])
{ {
checkmarkPanel.setCheckmarkValues(checkmarks); checkmarkPanel.setValues(checkmarks);
postInvalidate(); postInvalidate();
} }
@ -213,7 +213,7 @@ public class HabitCardView extends FrameLayout
scoreRing.setColor(color); scoreRing.setColor(color);
scoreRing.setPercentage(rand.nextFloat()); scoreRing.setPercentage(rand.nextFloat());
checkmarkPanel.setColor(color); checkmarkPanel.setColor(color);
checkmarkPanel.setCheckmarkValues(values); checkmarkPanel.setValues(values);
} }
private void refresh() private void refresh()

@ -0,0 +1,131 @@
/*
* 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.activities.habits.list.views;
import android.content.*;
import android.graphics.*;
import android.support.annotation.*;
import android.util.*;
import android.view.*;
import android.widget.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.habits.list.controllers.*;
import org.isoron.uhabits.utils.*;
import static org.isoron.uhabits.utils.AttributeSetUtils.*;
import static org.isoron.uhabits.utils.ColorUtils.*;
public class NumberButtonView extends TextView
{
private static Typeface TYPEFACE =
Typeface.create("sans-serif-condensed", Typeface.BOLD);
private int color;
private int value;
private int threshold;
private StyledResources res;
public NumberButtonView(@Nullable Context context)
{
super(context);
init();
}
public NumberButtonView(@Nullable Context context,
@Nullable AttributeSet attrs)
{
super(context, attrs);
init();
if (context != null && attrs != null)
{
int color = getIntAttribute(context, attrs, "color", 0);
int value = getIntAttribute(context, attrs, "value", 0);
int threshold = getIntAttribute(context, attrs, "threshold", 1);
setColor(getAndroidTestColor(color));
setThreshold(threshold);
setValue(value);
}
}
private static String formatValue(int v)
{
double fv = (double) v;
if(v >= 1e9) return String.format("%.2fG", fv / 1e9);
if(v >= 1e8) return String.format("%.0fM", fv / 1e6);
if(v >= 1e7) return String.format("%.1fM", fv / 1e6);
if(v >= 1e6) return String.format("%.2fM", fv / 1e6);
if(v >= 1e5) return String.format("%.0fk", fv / 1e3);
if(v >= 1e4) return String.format("%.1fk", fv / 1e3);
if(v >= 1e3) return String.format("%.2fk", fv / 1e3);
return String.format("%d", v);
}
public void setColor(int color)
{
this.color = color;
postInvalidate();
}
public void setController(final NumberButtonController controller)
{
setOnClickListener(v -> controller.onClick());
setOnLongClickListener(v -> controller.onLongClick());
}
public void setThreshold(int threshold)
{
this.threshold = threshold;
updateText();
}
public void setValue(int value)
{
this.value = value;
updateText();
}
private void init()
{
res = new StyledResources(getContext());
setWillNotDraw(false);
setMinHeight(
getResources().getDimensionPixelSize(R.dimen.checkmarkHeight));
setMinWidth(
getResources().getDimensionPixelSize(R.dimen.checkmarkWidth));
setFocusable(false);
setGravity(Gravity.CENTER);
setTypeface(TYPEFACE);
}
private void updateText()
{
int lowColor = res.getColor(R.attr.lowContrastTextColor);
setTextColor(value >= threshold ? color : lowColor);
setText(formatValue(value));
}
}

@ -0,0 +1,255 @@
/*
* 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.activities.habits.list.views;
import android.content.*;
import android.support.annotation.*;
import android.util.*;
import android.widget.*;
import org.isoron.uhabits.*;
import org.isoron.uhabits.activities.habits.list.*;
import org.isoron.uhabits.activities.habits.list.controllers.*;
import org.isoron.uhabits.models.*;
import org.isoron.uhabits.preferences.*;
import org.isoron.uhabits.utils.*;
import java.util.*;
import static android.view.View.MeasureSpec.*;
import static org.isoron.uhabits.utils.AttributeSetUtils.*;
import static org.isoron.uhabits.utils.ColorUtils.*;
public class NumberPanelView extends LinearLayout
implements Preferences.Listener
{
private static final int LEFT_TO_RIGHT = 0;
private static final int RIGHT_TO_LEFT = 1;
@Nullable
private Preferences prefs;
private int values[];
private int threshold;
private int nButtons;
private int color;
private Controller controller;
@NonNull
private Habit habit;
private int dataOffset;
public NumberPanelView(Context context)
{
super(context);
init();
}
public NumberPanelView(Context ctx, AttributeSet attrs)
{
super(ctx, attrs);
init();
if (ctx != null && attrs != null)
{
int paletteColor = getIntAttribute(ctx, attrs, "color", 0);
setColor(getAndroidTestColor(paletteColor));
setButtonCount(getIntAttribute(ctx, attrs, "button_count", 5));
setThreshold(getIntAttribute(ctx, attrs, "threshold", 1));
}
if(isInEditMode()) initEditMode();
}
private void initEditMode()
{
int values[] = new int[nButtons];
for(int i = 0; i < nButtons; i++)
values[i] = new Random().nextInt(threshold * 3);
setValues(values);
}
public NumberButtonView indexToButton(int i)
{
int position = i;
if (getCheckmarkOrder() == RIGHT_TO_LEFT) position = nButtons - i - 1;
return (NumberButtonView) getChildAt(position);
}
@Override
public void onCheckmarkOrderChanged()
{
setupButtons();
}
public void setButtonCount(int newButtonCount)
{
if (nButtons != newButtonCount)
{
nButtons = newButtonCount;
addButtons();
}
setupButtons();
}
public void setColor(int color)
{
this.color = color;
setupButtons();
}
public void setController(Controller controller)
{
this.controller = controller;
setupButtons();
}
public void setDataOffset(int dataOffset)
{
this.dataOffset = dataOffset;
setupButtons();
}
public void setHabit(@NonNull Habit habit)
{
this.habit = habit;
setupButtons();
}
public void setThreshold(int threshold)
{
this.threshold = threshold;
setupButtons();
}
public void setValues(int[] values)
{
this.values = values;
setupButtons();
}
@Override
protected void onAttachedToWindow()
{
super.onAttachedToWindow();
if (prefs != null) prefs.addListener(this);
}
@Override
protected void onDetachedFromWindow()
{
if (prefs != null) prefs.removeListener(this);
super.onDetachedFromWindow();
}
@Override
protected void onMeasure(int widthSpec, int heightSpec)
{
float buttonWidth = getResources().getDimension(R.dimen.checkmarkWidth);
float buttonHeight =
getResources().getDimension(R.dimen.checkmarkHeight);
float width = buttonWidth * nButtons;
widthSpec = makeMeasureSpec((int) width, EXACTLY);
heightSpec = makeMeasureSpec((int) buttonHeight, EXACTLY);
super.onMeasure(widthSpec, heightSpec);
}
private void addButtons()
{
removeAllViews();
for (int i = 0; i < nButtons; i++)
addView(new NumberButtonView(getContext()));
}
private int getCheckmarkOrder()
{
if (prefs == null) return LEFT_TO_RIGHT;
return prefs.shouldReverseCheckmarks() ? RIGHT_TO_LEFT : LEFT_TO_RIGHT;
}
private void init()
{
Context appContext = getContext().getApplicationContext();
if (appContext instanceof HabitsApplication)
{
HabitsApplication app = (HabitsApplication) appContext;
prefs = app.getComponent().getPreferences();
}
setWillNotDraw(false);
values = new int[0];
}
private void setupButtonControllers(long timestamp,
NumberButtonView buttonView)
{
if (controller == null) return;
if (!(getContext() instanceof ListHabitsActivity)) return;
ListHabitsActivity activity = (ListHabitsActivity) getContext();
NumberButtonControllerFactory buttonControllerFactory = activity
.getListHabitsComponent()
.getNumberButtonControllerFactory();
NumberButtonController buttonController =
buttonControllerFactory.create(habit, timestamp);
buttonController.setListener(controller);
buttonController.setView(buttonView);
buttonView.setController(buttonController);
}
private void setupButtons()
{
long timestamp = DateUtils.getStartOfToday();
long day = DateUtils.millisecondsInOneDay;
timestamp -= day * dataOffset;
for (int i = 0; i < nButtons; i++)
{
NumberButtonView buttonView = indexToButton(i);
if (i + dataOffset >= values.length) break;
buttonView.setValue(values[i + dataOffset]);
buttonView.setColor(color);
buttonView.setThreshold(threshold);
setupButtonControllers(timestamp, buttonView);
timestamp -= day;
}
}
public interface Controller extends NumberButtonController.Listener
{
}
}

@ -74,4 +74,14 @@ public class AttributeSetUtils
if (number != null) return Float.parseFloat(number); if (number != null) return Float.parseFloat(number);
else return defaultValue; else return defaultValue;
} }
public static int getIntAttribute(@NonNull Context context,
@NonNull AttributeSet attrs,
@NonNull String name,
int defaultValue)
{
String number = getAttribute(context, attrs, name, null);
if (number != null) return Integer.parseInt(number);
else return defaultValue;
}
} }

@ -0,0 +1,67 @@
<?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/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://isoron.org/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?windowBackgroundColor">
<org.isoron.uhabits.activities.habits.list.views.CheckmarkButtonView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:color="0"
app:value="2"/>
<org.isoron.uhabits.activities.habits.list.views.CheckmarkButtonView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:color="0"
app:value="0"/>
<org.isoron.uhabits.activities.habits.list.views.CheckmarkButtonView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:color="0"
app:value="1"/>
<org.isoron.uhabits.activities.habits.list.views.NumberButtonView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:threshold="10"
app:color="1"
app:value="5"/>
<org.isoron.uhabits.activities.habits.list.views.NumberButtonView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:threshold="10"
app:color="1"
app:value="50"/>
<org.isoron.uhabits.activities.habits.list.views.NumberButtonView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:threshold="10"
app:color="1"
app:value="25304"/>
</LinearLayout>

@ -0,0 +1,80 @@
<?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/>.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://isoron.org/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?windowBackgroundColor"
android:orientation="vertical">
<org.isoron.uhabits.activities.habits.list.views.NumberPanelView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:button_count="8"
app:color="1"
app:threshold="10"
/>
<org.isoron.uhabits.activities.habits.list.views.NumberPanelView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:button_count="8"
app:color="2"
app:threshold="5000"
/>
<org.isoron.uhabits.activities.habits.list.views.NumberPanelView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:button_count="8"
app:color="6"
app:threshold="10"
/>
<org.isoron.uhabits.activities.habits.list.views.CheckmarkPanelView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:button_count="8"
app:color="6"
/>
<org.isoron.uhabits.activities.habits.list.views.CheckmarkPanelView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:button_count="8"
app:color="4"
/>
<org.isoron.uhabits.activities.habits.list.views.NumberPanelView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:button_count="8"
app:color="10"
app:threshold="5"
/>
<org.isoron.uhabits.activities.habits.list.views.CheckmarkPanelView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:button_count="8"
app:color="10"
/>
</LinearLayout>
Loading…
Cancel
Save