mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
Replace star by ring
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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());
|
||||
int score = loader.scores.get(habit.getId());
|
||||
float percentage = (float) score / Score.MAX_VALUE;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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,22 +86,30 @@ public class RingView extends View
|
||||
postInvalidate();
|
||||
}
|
||||
|
||||
public void setMaxDiameter(float maxDiameter)
|
||||
{
|
||||
this.maxDiameter = maxDiameter;
|
||||
}
|
||||
|
||||
public void setLabel(String label)
|
||||
{
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public void setPercentage(float percentage)
|
||||
{
|
||||
this.percentage = percentage;
|
||||
postInvalidate();
|
||||
}
|
||||
|
||||
public void setPrecision(float precision)
|
||||
{
|
||||
this.precision = precision;
|
||||
postInvalidate();
|
||||
}
|
||||
|
||||
public void setThickness(float thickness)
|
||||
{
|
||||
this.thickness = thickness;
|
||||
postInvalidate();
|
||||
}
|
||||
|
||||
public void setText(String text)
|
||||
{
|
||||
this.text = text;
|
||||
postInvalidate();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
pRing = new TextPaint();
|
||||
@@ -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);
|
||||
em = pRing.measureText("M");
|
||||
|
||||
width = Math.max(width, labelLayout.getWidth());
|
||||
height = (int) (diameter + labelLayout.getHeight() + labelMarginTop);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,16 +19,22 @@
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/llOuter"
|
||||
style="@style/ListHabits.Item">
|
||||
xmlns:habit="http://isoron.org/android"
|
||||
android:id="@+id/llOuter"
|
||||
style="@style/ListHabits.Item">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/llInner"
|
||||
style="@style/ListHabits.HabitCard">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvStar"
|
||||
style="@style/ListHabits.Star" />
|
||||
<org.isoron.uhabits.views.RingView
|
||||
android:layout_height="15dp"
|
||||
android:layout_width="15dp"
|
||||
android:id="@+id/scoreRing"
|
||||
habit:thickness="3"
|
||||
android:layout_marginTop="0dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_marginLeft="8dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/label"
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
-->
|
||||
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://isoron.org/android"
|
||||
xmlns:habit="http://isoron.org/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -43,15 +43,23 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
android:orientation="vertical">
|
||||
|
||||
<org.isoron.uhabits.views.RingView
|
||||
android:id="@+id/scoreRing"
|
||||
style="@style/SmallDataView"
|
||||
android:layout_width="100dp"
|
||||
app:label="@string/strength"
|
||||
app:maxDiameter="80"
|
||||
app:textSize="@dimen/smallTextSize"/>
|
||||
android:layout_width="75dp"
|
||||
android:layout_height="75dp"
|
||||
habit:percentage="0"
|
||||
habit:thickness="10"
|
||||
habit:textSize="12"
|
||||
android:layout_margin="10dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/habit_strength"
|
||||
android:textSize="@dimen/smallTextSize"
|
||||
android:textColor="?mediumContrastTextColor"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user