From aee5d975db13b277d86d9152fdb549cf5bc7786f Mon Sep 17 00:00:00 2001 From: Alinson Xavier Date: Thu, 21 Apr 2016 20:02:38 -0400 Subject: [PATCH] Replace star by ring --- .../uhabits/unit/views/RingViewTest.java | 10 +- .../uhabits/fragments/ListHabitsFragment.java | 3 +- .../uhabits/fragments/ShowHabitFragment.java | 1 + .../isoron/uhabits/helpers/ColorHelper.java | 6 + .../uhabits/helpers/ListHabitsHelper.java | 51 ++------ .../org/isoron/uhabits/helpers/UIHelper.java | 23 +++- .../org/isoron/uhabits/views/RingView.java | 113 ++++++++++-------- app/src/main/res/layout/list_habits_item.xml | 16 ++- app/src/main/res/layout/show_habit.xml | 22 ++-- 9 files changed, 137 insertions(+), 108 deletions(-) diff --git a/app/src/androidTest/java/org/isoron/uhabits/unit/views/RingViewTest.java b/app/src/androidTest/java/org/isoron/uhabits/unit/views/RingViewTest.java index 6d85136e1..df0a0c422 100644 --- a/app/src/androidTest/java/org/isoron/uhabits/unit/views/RingViewTest.java +++ b/app/src/androidTest/java/org/isoron/uhabits/unit/views/RingViewTest.java @@ -42,10 +42,10 @@ public class RingViewTest extends ViewTest super.setup(); view = new RingView(targetContext); - view.setLabel("Hello world"); +// view.setLabel("Hello world"); view.setPercentage(0.6f); view.setColor(ColorHelper.CSV_PALETTE[0]); - view.setMaxDiameter(dpToPixels(100)); +// view.setMaxDiameter(dpToPixels(100)); } @Test @@ -58,7 +58,7 @@ public class RingViewTest extends ViewTest @Test public void testRender_withLongLabel() throws IOException { - view.setLabel("The quick brown fox jumps over the lazy fox"); +// view.setLabel("The quick brown fox jumps over the lazy fox"); measureView(dpToPixels(100), dpToPixels(100), view); assertRenders(view, "RingView/renderLongLabel.png"); @@ -67,9 +67,9 @@ public class RingViewTest extends ViewTest @Test public void testRender_withDifferentParams() throws IOException { - view.setLabel("Habit Strength"); +// view.setLabel("Habit Strength"); view.setPercentage(0.25f); - view.setMaxDiameter(dpToPixels(50)); +// view.setMaxDiameter(dpToPixels(50)); view.setColor(ColorHelper.CSV_PALETTE[5]); measureView(dpToPixels(200), dpToPixels(200), view); diff --git a/app/src/main/java/org/isoron/uhabits/fragments/ListHabitsFragment.java b/app/src/main/java/org/isoron/uhabits/fragments/ListHabitsFragment.java index 178f84954..9d87c7282 100644 --- a/app/src/main/java/org/isoron/uhabits/fragments/ListHabitsFragment.java +++ b/app/src/main/java/org/isoron/uhabits/fragments/ListHabitsFragment.java @@ -61,6 +61,7 @@ import org.isoron.uhabits.helpers.DateHelper; import org.isoron.uhabits.helpers.HintManager; import org.isoron.uhabits.helpers.ListHabitsHelper; import org.isoron.uhabits.helpers.ReminderHelper; +import org.isoron.uhabits.helpers.UIHelper; import org.isoron.uhabits.helpers.UIHelper.OnSavedListener; import org.isoron.uhabits.loaders.HabitListLoader; import org.isoron.uhabits.models.Habit; @@ -121,7 +122,7 @@ public class ListHabitsFragment extends Fragment loader.setCheckmarkCount(helper.getButtonCount()); llHint.setOnClickListener(this); - tvStarEmpty.setTypeface(helper.getFontawesome()); + tvStarEmpty.setTypeface(UIHelper.getFontAwesome()); adapter = new HabitListAdapter(getActivity(), loader); adapter.setSelectedPositions(selectedPositions); diff --git a/app/src/main/java/org/isoron/uhabits/fragments/ShowHabitFragment.java b/app/src/main/java/org/isoron/uhabits/fragments/ShowHabitFragment.java index a89d23e29..42c06e1c4 100644 --- a/app/src/main/java/org/isoron/uhabits/fragments/ShowHabitFragment.java +++ b/app/src/main/java/org/isoron/uhabits/fragments/ShowHabitFragment.java @@ -166,6 +166,7 @@ public class ShowHabitFragment extends Fragment int androidColor = ColorHelper.getColor(getActivity(), habit.color); scoreRing.setColor(androidColor); scoreRing.setPercentage(percentage); + scoreRing.setText(String.format("%.0f%%", 100 * percentage)); } private void updateHeaders(View view) diff --git a/app/src/main/java/org/isoron/uhabits/helpers/ColorHelper.java b/app/src/main/java/org/isoron/uhabits/helpers/ColorHelper.java index 8f6dd8480..bafffd809 100644 --- a/app/src/main/java/org/isoron/uhabits/helpers/ColorHelper.java +++ b/app/src/main/java/org/isoron/uhabits/helpers/ColorHelper.java @@ -112,6 +112,12 @@ public class ColorHelper return setHSVParameter(color, newValue, 2); } + public static int setAlpha(int color, float newAlpha) + { + int intAlpha = (int) (newAlpha * 255); + return Color.argb(intAlpha, Color.red(color), Color.green(color), Color.blue(color)); + } + public static int setMinValue(int color, float newValue) { float hsv[] = new float[3]; diff --git a/app/src/main/java/org/isoron/uhabits/helpers/ListHabitsHelper.java b/app/src/main/java/org/isoron/uhabits/helpers/ListHabitsHelper.java index 385cce4b7..a389bf827 100644 --- a/app/src/main/java/org/isoron/uhabits/helpers/ListHabitsHelper.java +++ b/app/src/main/java/org/isoron/uhabits/helpers/ListHabitsHelper.java @@ -20,7 +20,6 @@ package org.isoron.uhabits.helpers; import android.content.Context; -import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.view.LayoutInflater; import android.view.MotionEvent; @@ -33,6 +32,7 @@ import org.isoron.uhabits.R; import org.isoron.uhabits.loaders.HabitListLoader; import org.isoron.uhabits.models.Habit; import org.isoron.uhabits.models.Score; +import org.isoron.uhabits.views.RingView; import java.util.GregorianCalendar; @@ -43,7 +43,6 @@ public class ListHabitsHelper private final Context context; private final HabitListLoader loader; - private Typeface fontawesome; public ListHabitsHelper(Context context, HabitListLoader loader) { @@ -52,12 +51,6 @@ public class ListHabitsHelper lowContrastColor = UIHelper.getStyledColor(context, R.attr.lowContrastTextColor); mediumContrastColor = UIHelper.getStyledColor(context, R.attr.mediumContrastTextColor); - fontawesome = Typeface.createFromAsset(context.getAssets(), "fontawesome-webfont.ttf"); - } - - public Typeface getFontawesome() - { - return fontawesome; } public int getButtonCount() @@ -105,46 +98,24 @@ public class ListHabitsHelper public void initializeLabelAndIcon(View itemView) { - TextView tvStar = (TextView) itemView.findViewById(R.id.tvStar); - tvStar.setTypeface(getFontawesome()); - LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(getHabitNameWidth(), LinearLayout.LayoutParams.WRAP_CONTENT, 1); itemView.findViewById(R.id.label).setLayoutParams(params); } - public void updateNameAndIcon(Habit habit, TextView tvStar, TextView tvName) + public void updateNameAndIcon(Habit habit, RingView ring, TextView tvName) { int activeColor = getActiveColor(habit); tvName.setText(habit.name); tvName.setTextColor(activeColor); - if (habit.isArchived()) - { - tvStar.setText(context.getString(R.string.fa_archive)); - tvStar.setTextColor(activeColor); - } - else - { - int score = loader.scores.get(habit.getId()); - - if (score < Score.HALF_STAR_CUTOFF) - { - tvStar.setText(context.getString(R.string.fa_star_o)); - tvStar.setTextColor(lowContrastColor); - } - else if (score < Score.FULL_STAR_CUTOFF) - { - tvStar.setText(context.getString(R.string.fa_star_half_o)); - tvStar.setTextColor(lowContrastColor); - } - else - { - tvStar.setText(context.getString(R.string.fa_star)); - tvStar.setTextColor(activeColor); - } - } + int score = loader.scores.get(habit.getId()); + float percentage = (float) score / Score.MAX_VALUE; + + ring.setColor(activeColor); + ring.setPercentage(percentage); + ring.setPrecision(0.2f); } public void updateCheckmark(int activeColor, TextView tvCheck, int check) @@ -184,7 +155,7 @@ public class ListHabitsHelper public void updateHabitCard(View view, Habit habit, boolean selected) { - TextView tvStar = ((TextView) view.findViewById(R.id.tvStar)); + RingView scoreRing = ((RingView) view.findViewById(R.id.scoreRing)); TextView tvName = (TextView) view.findViewById(R.id.label); LinearLayout llInner = (LinearLayout) view.findViewById(R.id.llInner); LinearLayout llButtons = (LinearLayout) view.findViewById(R.id.llButtons); @@ -192,7 +163,7 @@ public class ListHabitsHelper llInner.setTag(R.string.habit_key, habit.getId()); llInner.setOnTouchListener(new HotspotTouchListener()); - updateNameAndIcon(habit, tvStar, tvName); + updateNameAndIcon(habit, scoreRing, tvName); updateCheckmarkButtons(habit, llButtons); updateHabitCardBackground(llInner, selected); } @@ -227,7 +198,7 @@ public class ListHabitsHelper { View check = inflater.inflate(R.layout.list_habits_item_check, null); TextView btCheck = (TextView) check.findViewById(R.id.tvCheck); - btCheck.setTypeface(fontawesome); + btCheck.setTypeface(UIHelper.getFontAwesome()); btCheck.setOnLongClickListener(onLongClickListener); btCheck.setOnClickListener(onClickListener); btCheck.setHapticFeedbackEnabled(false); diff --git a/app/src/main/java/org/isoron/uhabits/helpers/UIHelper.java b/app/src/main/java/org/isoron/uhabits/helpers/UIHelper.java index a081e6aef..301eca48a 100644 --- a/app/src/main/java/org/isoron/uhabits/helpers/UIHelper.java +++ b/app/src/main/java/org/isoron/uhabits/helpers/UIHelper.java @@ -50,13 +50,26 @@ public abstract class UIHelper public static final int THEME_LIGHT = 0; public static final int THEME_DARK = 1; - private static Typeface fontawesome; + private static Typeface fontAwesome; public interface OnSavedListener { void onSaved(Command command, Object savedObject); } + public static Typeface getFontAwesome() + { + if(fontAwesome == null) + { + Context context = HabitsApplication.getContext(); + if(context == null) throw new RuntimeException("Could not find application context"); + + fontAwesome = Typeface.createFromAsset(context.getAssets(), "fontawesome-webfont.ttf"); + } + + return fontAwesome; + } + public static void showSoftKeyboard(View view) { InputMethodManager imm = (InputMethodManager) view.getContext() @@ -102,6 +115,14 @@ public abstract class UIHelper else return defaultValue; } + public static boolean getBooleanAttribute(Context context, AttributeSet attrs, String name, + boolean defaultValue) + { + String boolText = getAttribute(context, attrs, name, null); + if(boolText != null) return Boolean.parseBoolean(boolText); + else return defaultValue; + } + public static float getFloatAttribute(Context context, AttributeSet attrs, String name, float defaultValue) { diff --git a/app/src/main/java/org/isoron/uhabits/views/RingView.java b/app/src/main/java/org/isoron/uhabits/views/RingView.java index db1cc1a58..bdfe4a49d 100644 --- a/app/src/main/java/org/isoron/uhabits/views/RingView.java +++ b/app/src/main/java/org/isoron/uhabits/views/RingView.java @@ -24,33 +24,34 @@ import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.RectF; -import android.text.Layout; -import android.text.StaticLayout; import android.text.TextPaint; import android.util.AttributeSet; import android.view.View; import org.isoron.uhabits.R; +import org.isoron.uhabits.helpers.ColorHelper; import org.isoron.uhabits.helpers.UIHelper; public class RingView extends View { + private float precision; + private boolean enableFontAwesome; + private int color; private float percentage; - private float labelMarginTop; private TextPaint pRing; - private String label; private RectF rect; - private StaticLayout labelLayout; - private int width; - private int height; - private float diameter; + private int diameter; - private float maxDiameter; private float textSize; - private int textColor; + + private float thickness; + private int backgroundColor; + private int inactiveColor; + private float em; + private String text; public RingView(Context context) { @@ -62,9 +63,20 @@ public class RingView extends View { super(context, attrs); - this.label = UIHelper.getAttribute(context, attrs, "label", "Label"); - this.maxDiameter = UIHelper.getFloatAttribute(context, attrs, "maxDiameter", 100); - this.maxDiameter = UIHelper.dpToPixels(context, maxDiameter); + percentage = UIHelper.getFloatAttribute(context, attrs, "percentage", 0); + precision = UIHelper.getFloatAttribute(context, attrs, "precision", 0.01f); + + thickness = UIHelper.getFloatAttribute(context, attrs, "thickness", 0); + thickness = UIHelper.dpToPixels(context, thickness); + + float defaultTextSize = context.getResources().getDimension(R.dimen.smallTextSize); + textSize = UIHelper.getFloatAttribute(context, attrs, "textSize", defaultTextSize); + textSize = UIHelper.spToPixels(context, textSize); + + text = UIHelper.getAttribute(context, attrs, "text", ""); + + enableFontAwesome = UIHelper.getBooleanAttribute(context, attrs, "enableFontAwesome", false); + init(); } @@ -74,19 +86,27 @@ public class RingView extends View postInvalidate(); } - public void setMaxDiameter(float maxDiameter) + public void setPercentage(float percentage) { - this.maxDiameter = maxDiameter; + this.percentage = percentage; + postInvalidate(); } - public void setLabel(String label) + public void setPrecision(float precision) { - this.label = label; + this.precision = precision; + postInvalidate(); } - public void setPercentage(float percentage) + public void setThickness(float thickness) { - this.percentage = percentage; + this.thickness = thickness; + postInvalidate(); + } + + public void setText(String text) + { + this.text = text; postInvalidate(); } @@ -98,8 +118,10 @@ public class RingView extends View pRing.setTextAlign(Paint.Align.CENTER); backgroundColor = UIHelper.getStyledColor(getContext(), R.attr.cardBackgroundColor); - textColor = UIHelper.getStyledColor(getContext(), R.attr.mediumContrastTextColor); - textSize = getResources().getDimension(R.dimen.smallTextSize); + + color = ColorHelper.CSV_PALETTE[6]; + inactiveColor = UIHelper.getStyledColor(getContext(), R.attr.highContrastTextColor); + inactiveColor = ColorHelper.setAlpha(inactiveColor, 0.1f); rect = new RectF(); } @@ -110,48 +132,41 @@ public class RingView extends View { super.onMeasure(widthMeasureSpec, heightMeasureSpec); - width = MeasureSpec.getSize(widthMeasureSpec); - height = MeasureSpec.getSize(heightMeasureSpec); - - diameter = Math.min(maxDiameter, width); + int width = MeasureSpec.getSize(widthMeasureSpec); + int height = MeasureSpec.getSize(heightMeasureSpec); + diameter = Math.min(height, width); pRing.setTextSize(textSize); - labelMarginTop = textSize * 0.80f; - labelLayout = new StaticLayout(label, pRing, width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0f, - false); - - width = Math.max(width, labelLayout.getWidth()); - height = (int) (diameter + labelLayout.getHeight() + labelMarginTop); + em = pRing.measureText("M"); - setMeasuredDimension(width, height); + setMeasuredDimension(diameter, diameter); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); - float thickness = diameter * 0.15f; pRing.setColor(color); rect.set(0, 0, diameter, diameter); - rect.offset((width - diameter) / 2, 0); - canvas.drawArc(rect, -90, 360 * percentage, true, pRing); - int grey = UIHelper.getStyledColor(getContext(), R.attr.lowContrastTextColor); - pRing.setColor(grey); - canvas.drawArc(rect, 360 * percentage - 90 + 2, 360 * (1 - percentage) - 4, true, pRing); + float angle = 360 * Math.round(percentage / precision) * precision; - pRing.setColor(backgroundColor); - rect.inset(thickness, thickness); - canvas.drawArc(rect, -90, 360, true, pRing); + canvas.drawArc(rect, -90, angle, true, pRing); - pRing.setColor(textColor); - pRing.setTextSize(textSize); - float lineHeight = pRing.getFontSpacing(); - canvas.drawText(String.format("%.0f%%", percentage * 100), rect.centerX(), - rect.centerY() + lineHeight / 3, pRing); - pRing.setTextSize(textSize); - canvas.translate(width / 2, diameter + labelMarginTop); - labelLayout.draw(canvas); + pRing.setColor(inactiveColor); + canvas.drawArc(rect, angle - 90, 360 - angle, true, pRing); + + if(thickness > 0) + { + pRing.setColor(backgroundColor); + rect.inset(thickness, thickness); + canvas.drawArc(rect, -90, 360, true, pRing); + + pRing.setColor(color); + pRing.setTextSize(textSize); + if(enableFontAwesome) pRing.setTypeface(UIHelper.getFontAwesome()); + canvas.drawText(text, rect.centerX(), rect.centerY() + 0.5f * em, pRing); + } } } diff --git a/app/src/main/res/layout/list_habits_item.xml b/app/src/main/res/layout/list_habits_item.xml index bcd2d4785..63a766d35 100644 --- a/app/src/main/res/layout/list_habits_item.xml +++ b/app/src/main/res/layout/list_habits_item.xml @@ -19,16 +19,22 @@ --> + xmlns:habit="http://isoron.org/android" + android:id="@+id/llOuter" + style="@style/ListHabits.Item"> - + + android:orientation="vertical"> + android:layout_width="75dp" + android:layout_height="75dp" + habit:percentage="0" + habit:thickness="10" + habit:textSize="12" + android:layout_margin="10dp"/> + +