mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
Implement NumberButtonView and related classes
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setButtonCount(int newButtonCount)
|
@Override
|
||||||
|
public void onCheckmarkOrderChanged()
|
||||||
{
|
{
|
||||||
if(nButtons != newButtonCount)
|
setupButtons();
|
||||||
{
|
|
||||||
nButtons = newButtonCount;
|
|
||||||
addCheckmarkButtons();
|
|
||||||
}
|
|
||||||
|
|
||||||
setupCheckmarkButtons();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCheckmarkValues(int[] checkmarkValues)
|
public void setButtonCount(int newButtonCount)
|
||||||
{
|
{
|
||||||
this.checkmarkValues = checkmarkValues;
|
if (nButtons != newButtonCount)
|
||||||
setupCheckmarkButtons();
|
{
|
||||||
|
nButtons = newButtonCount;
|
||||||
|
addButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
setupButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
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,21 +176,31 @@ 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()
|
||||||
{
|
{
|
||||||
Context appContext = getContext().getApplicationContext();
|
Context appContext = getContext().getApplicationContext();
|
||||||
if(appContext instanceof HabitsApplication)
|
if (appContext instanceof HabitsApplication)
|
||||||
{
|
{
|
||||||
HabitsApplication app = (HabitsApplication) appContext;
|
HabitsApplication app = (HabitsApplication) appContext;
|
||||||
prefs = app.getComponent().getPreferences();
|
prefs = app.getComponent().getPreferences();
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
67
app/src/main/res/layout/list_habits_button_preview.xml
Normal file
67
app/src/main/res/layout/list_habits_button_preview.xml
Normal file
@@ -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>
|
||||||
80
app/src/main/res/layout/list_habits_panel_preview.xml
Normal file
80
app/src/main/res/layout/list_habits_panel_preview.xml
Normal file
@@ -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>
|
||||||
Reference in New Issue
Block a user