mirror of https://github.com/iSoron/uhabits.git
parent
1ff3c1c857
commit
a1f05714ba
@ -0,0 +1,128 @@
|
||||
package org.isoron.uhabits.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.view.View;
|
||||
|
||||
import org.isoron.helpers.ColorHelper;
|
||||
import org.isoron.helpers.DateHelper;
|
||||
import org.isoron.uhabits.models.Habit;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
public class HabitStreakView extends View
|
||||
{
|
||||
private Habit habit;
|
||||
private int columnWidth, columnHeight, nColumns;
|
||||
|
||||
private Paint pText, pBar;
|
||||
private long streaks[];
|
||||
|
||||
private long streakStart[], streakEnd[], streakLength[];
|
||||
private long maxStreakLength;
|
||||
|
||||
private int barHeaderHeight;
|
||||
|
||||
private int[] colors;
|
||||
|
||||
public HabitStreakView(Context context, Habit habit, int columnWidth)
|
||||
{
|
||||
super(context);
|
||||
this.habit = habit;
|
||||
this.columnWidth = columnWidth;
|
||||
|
||||
pText = new Paint();
|
||||
pText.setColor(Color.LTGRAY);
|
||||
pText.setTextAlign(Paint.Align.CENTER);
|
||||
pText.setTextSize(columnWidth * 0.5f);
|
||||
pText.setAntiAlias(true);
|
||||
|
||||
pBar = new Paint();
|
||||
pBar.setTextAlign(Paint.Align.CENTER);
|
||||
pBar.setTextSize(columnWidth * 0.5f);
|
||||
pBar.setAntiAlias(true);
|
||||
|
||||
columnHeight = 8 * columnWidth;
|
||||
barHeaderHeight = columnWidth;
|
||||
|
||||
colors = new int[4];
|
||||
|
||||
colors[0] = Color.rgb(230, 230, 230);
|
||||
colors[3] = habit.color;
|
||||
colors[1] = ColorHelper.mixColors(colors[0], colors[3], 0.66f);
|
||||
colors[2] = ColorHelper.mixColors(colors[0], colors[3], 0.33f);
|
||||
|
||||
fetchStreaks();
|
||||
}
|
||||
|
||||
private void fetchStreaks()
|
||||
{
|
||||
streaks = habit.getStreaks();
|
||||
streakStart = new long[streaks.length / 2];
|
||||
streakEnd = new long[streaks.length / 2];
|
||||
streakLength = new long[streaks.length / 2];
|
||||
|
||||
for(int i=0; i<streaks.length / 2; i++)
|
||||
{
|
||||
streakStart[i] = streaks[i * 2];
|
||||
streakEnd[i] = streaks[i * 2 + 1];
|
||||
streakLength[i] = (streakEnd[i] - streakStart[i]) / DateHelper.millisecondsInOneDay + 1;
|
||||
maxStreakLength = Math.max(maxStreakLength, streakLength[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
|
||||
{
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(getMeasuredWidth(), columnHeight + 2*barHeaderHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh)
|
||||
{
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
nColumns = w / columnWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas)
|
||||
{
|
||||
super.onDraw(canvas);
|
||||
|
||||
float lineHeight = pText.getFontSpacing();
|
||||
float barHeaderOffset = lineHeight * 0.4f;
|
||||
|
||||
int start = Math.max(0, streakStart.length - nColumns);
|
||||
SimpleDateFormat dfMonth = new SimpleDateFormat("MMM");
|
||||
|
||||
String previousMonth = "";
|
||||
|
||||
for (int offset = 0; offset < nColumns && start+offset < streakStart.length; offset++)
|
||||
{
|
||||
String month = dfMonth.format(streakStart[start+offset]);
|
||||
|
||||
long l = streakLength[offset+start];
|
||||
double lRelative = ((double) l) / maxStreakLength;
|
||||
|
||||
pBar.setColor(colors[(int) Math.floor(lRelative*3)]);
|
||||
|
||||
int height = (int) (columnHeight * lRelative);
|
||||
Rect r = new Rect(0,0,columnWidth-2, height);
|
||||
r.offset(offset * columnWidth, barHeaderHeight + columnHeight - height);
|
||||
|
||||
canvas.drawRect(r, pBar);
|
||||
canvas.drawText(Long.toString(streakLength[offset+start]), r.centerX(), r.top - barHeaderOffset, pBar);
|
||||
|
||||
if(!month.equals(previousMonth))
|
||||
canvas.drawText(month, r.centerX(), r.bottom + lineHeight * 1.2f, pText);
|
||||
|
||||
previousMonth = month;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package org.isoron.uhabits.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
import android.view.View;
|
||||
|
||||
public class RingView extends View
|
||||
{
|
||||
|
||||
private int size;
|
||||
private int color;
|
||||
private float perc;
|
||||
private Paint pRing;
|
||||
private float lineHeight;
|
||||
private String label;
|
||||
|
||||
public RingView(Context context, int size, int color, float perc, String label)
|
||||
{
|
||||
super(context);
|
||||
this.size = size;
|
||||
this.color = color;
|
||||
this.perc = perc;
|
||||
|
||||
pRing = new Paint();
|
||||
pRing.setColor(color);
|
||||
pRing.setAntiAlias(true);
|
||||
pRing.setTextAlign(Paint.Align.CENTER);
|
||||
pRing.setTextSize(size * 0.15f);
|
||||
|
||||
this.label = label;
|
||||
|
||||
lineHeight = pRing.getFontSpacing();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
|
||||
{
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
setMeasuredDimension(size, size + (int) (2*lineHeight));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas)
|
||||
{
|
||||
super.onDraw(canvas);
|
||||
float thickness = size * 0.15f;
|
||||
|
||||
pRing.setColor(color);
|
||||
RectF r = new RectF(0, 0, size, size);
|
||||
canvas.drawArc(r, -90, 360 * perc, true, pRing);
|
||||
|
||||
|
||||
pRing.setColor(Color.rgb(230, 230, 230));
|
||||
canvas.drawArc(r, 360 * perc - 90 + 2, 360 * (1-perc) - 4, true, pRing);
|
||||
|
||||
pRing.setColor(Color.WHITE);
|
||||
r.inset(thickness, thickness);
|
||||
canvas.drawArc(r, -90, 360, true, pRing);
|
||||
|
||||
pRing.setColor(Color.GRAY);
|
||||
canvas.drawText(String.format("%.2f%%", perc*100), r.centerX(), r.centerY()+lineHeight/3, pRing);
|
||||
canvas.drawText(label, size/2, size + lineHeight * 1.2f, pRing);
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:top="0dp"
|
||||
android:bottom="0dp"
|
||||
android:left="0dp"
|
||||
android:right="0dp">
|
||||
<shape>
|
||||
<solid android:color="#d6d6d6" />
|
||||
</shape>
|
||||
</item>
|
||||
<item
|
||||
android:top="0dp"
|
||||
android:bottom="1dp"
|
||||
android:left="0dp"
|
||||
android:right="0dp">
|
||||
<shape>
|
||||
<solid android:color="#c0c0c0" />
|
||||
</shape>
|
||||
</item>
|
||||
<item
|
||||
android:top="0dp"
|
||||
android:bottom="1.5dp"
|
||||
android:left="0dp"
|
||||
android:right="0dp">
|
||||
<shape>
|
||||
<solid android:color="#d6d6d6"/>
|
||||
</shape>
|
||||
</item>
|
||||
<item
|
||||
android:top="0.5dp"
|
||||
android:bottom="1.5dp"
|
||||
android:left="0.5dp"
|
||||
android:right="0.5dp">
|
||||
<shape>
|
||||
<solid android:color="@color/white"/>
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
|
||||
<item android:top="40dp">
|
||||
<shape android:shape="rectangle" >
|
||||
<gradient
|
||||
android:startColor="#30000000"
|
||||
android:endColor="#00000000"
|
||||
android:angle="270"/>
|
||||
</shape>
|
||||
</item>
|
||||
<item android:top="21dp" android:bottom="2dp">
|
||||
<shape android:shape="rectangle" >
|
||||
<gradient
|
||||
android:angle="270"
|
||||
android:endColor="#ccffffff"
|
||||
android:startColor="#ffffff" />
|
||||
</shape>
|
||||
</item>
|
||||
<item android:bottom="21dp">
|
||||
<shape android:shape="rectangle" >
|
||||
<solid android:color="#ffffff" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</layer-list>
|
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="habitsListHeaderStyle">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:layout_alignParentTop">true</item>
|
||||
<item name="android:background">#f0f0f0</item>
|
||||
<item name="android:elevation">2dp</item>
|
||||
<item name="android:paddingRight">4dp</item>
|
||||
</style>
|
||||
|
||||
<style name="habitsListCheckStyle">
|
||||
<item name="android:focusable">false</item>
|
||||
<item name="android:minHeight">42dp</item>
|
||||
<item name="android:minWidth">42dp</item>
|
||||
<item name="android:gravity">center</item>
|
||||
<item name="android:background">@drawable/ripple_background</item>
|
||||
</style>
|
||||
</resources>
|
Loading…
Reference in new issue