mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-07 01:28:52 -06:00
Fix transparency on widgets
This commit is contained in:
@@ -62,7 +62,7 @@ public class HabitScoreViewTest extends ViewTest
|
|||||||
@Test
|
@Test
|
||||||
public void testRender_withTransparentBackground() throws Throwable
|
public void testRender_withTransparentBackground() throws Throwable
|
||||||
{
|
{
|
||||||
view.setIsBackgroundTransparent(true);
|
view.setIsTransparencyEnabled(true);
|
||||||
assertRenders(view, "HabitScoreView/renderTransparent.png");
|
assertRenders(view, "HabitScoreView/renderTransparent.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,8 @@ public class CheckmarkWidgetView extends HabitWidgetView implements HabitDataVie
|
|||||||
ring = (RingView) findViewById(R.id.scoreRing);
|
ring = (RingView) findViewById(R.id.scoreRing);
|
||||||
label = (TextView) findViewById(R.id.label);
|
label = (TextView) findViewById(R.id.label);
|
||||||
|
|
||||||
|
if(ring != null) ring.setIsTransparencyEnabled(true);
|
||||||
|
|
||||||
if(isInEditMode())
|
if(isInEditMode())
|
||||||
{
|
{
|
||||||
percentage = 0.75f;
|
percentage = 0.75f;
|
||||||
|
|||||||
@@ -20,7 +20,9 @@
|
|||||||
package org.isoron.uhabits.views;
|
package org.isoron.uhabits.views;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
import android.graphics.PorterDuffXfermode;
|
import android.graphics.PorterDuffXfermode;
|
||||||
@@ -71,11 +73,14 @@ public class HabitScoreView extends ScrollableDataView implements HabitDataView
|
|||||||
private int[] scores;
|
private int[] scores;
|
||||||
|
|
||||||
private int primaryColor;
|
private int primaryColor;
|
||||||
private boolean isBackgroundTransparent;
|
|
||||||
private int bucketSize = 7;
|
private int bucketSize = 7;
|
||||||
private int footerHeight;
|
private int footerHeight;
|
||||||
private int backgroundColor;
|
private int backgroundColor;
|
||||||
|
|
||||||
|
private Bitmap drawingCache;
|
||||||
|
private Canvas cacheCanvas;
|
||||||
|
private boolean isTransparencyEnabled;
|
||||||
|
|
||||||
public HabitScoreView(Context context)
|
public HabitScoreView(Context context)
|
||||||
{
|
{
|
||||||
super(context);
|
super(context);
|
||||||
@@ -168,6 +173,13 @@ public class HabitScoreView extends ScrollableDataView implements HabitDataView
|
|||||||
pGraph.setTextSize(baseSize * 0.5f);
|
pGraph.setTextSize(baseSize * 0.5f);
|
||||||
pGraph.setStrokeWidth(baseSize * 0.1f);
|
pGraph.setStrokeWidth(baseSize * 0.1f);
|
||||||
pGrid.setStrokeWidth(baseSize * 0.025f);
|
pGrid.setStrokeWidth(baseSize * 0.025f);
|
||||||
|
|
||||||
|
if(isTransparencyEnabled)
|
||||||
|
{
|
||||||
|
if (drawingCache != null) drawingCache.recycle();
|
||||||
|
drawingCache = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||||
|
cacheCanvas = new Canvas(drawingCache);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshData()
|
public void refreshData()
|
||||||
@@ -206,12 +218,24 @@ public class HabitScoreView extends ScrollableDataView implements HabitDataView
|
|||||||
protected void onDraw(Canvas canvas)
|
protected void onDraw(Canvas canvas)
|
||||||
{
|
{
|
||||||
super.onDraw(canvas);
|
super.onDraw(canvas);
|
||||||
|
Canvas activeCanvas;
|
||||||
|
|
||||||
|
if(isTransparencyEnabled)
|
||||||
|
{
|
||||||
|
activeCanvas = cacheCanvas;
|
||||||
|
drawingCache.eraseColor(Color.TRANSPARENT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
activeCanvas = canvas;
|
||||||
|
}
|
||||||
|
|
||||||
if (habit == null || scores == null) return;
|
if (habit == null || scores == null) return;
|
||||||
|
|
||||||
rect.set(0, 0, nColumns * columnWidth, columnHeight);
|
rect.set(0, 0, nColumns * columnWidth, columnHeight);
|
||||||
rect.offset(0, paddingTop);
|
rect.offset(0, paddingTop);
|
||||||
|
|
||||||
drawGrid(canvas, rect);
|
drawGrid(activeCanvas, rect);
|
||||||
|
|
||||||
pText.setColor(textColor);
|
pText.setColor(textColor);
|
||||||
pGraph.setColor(primaryColor);
|
pGraph.setColor(primaryColor);
|
||||||
@@ -241,20 +265,23 @@ public class HabitScoreView extends ScrollableDataView implements HabitDataView
|
|||||||
|
|
||||||
if (!prevRect.isEmpty())
|
if (!prevRect.isEmpty())
|
||||||
{
|
{
|
||||||
drawLine(canvas, prevRect, rect);
|
drawLine(activeCanvas, prevRect, rect);
|
||||||
drawMarker(canvas, prevRect);
|
drawMarker(activeCanvas, prevRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (k == nColumns - 1) drawMarker(canvas, rect);
|
if (k == nColumns - 1) drawMarker(activeCanvas, rect);
|
||||||
|
|
||||||
prevRect.set(rect);
|
prevRect.set(rect);
|
||||||
rect.set(0, 0, columnWidth, columnHeight);
|
rect.set(0, 0, columnWidth, columnHeight);
|
||||||
rect.offset(k * columnWidth, paddingTop);
|
rect.offset(k * columnWidth, paddingTop);
|
||||||
|
|
||||||
drawFooter(canvas, rect, currentDate);
|
drawFooter(activeCanvas, rect, currentDate);
|
||||||
|
|
||||||
currentDate += bucketSize * DateHelper.millisecondsInOneDay;
|
currentDate += bucketSize * DateHelper.millisecondsInOneDay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(activeCanvas != canvas)
|
||||||
|
canvas.drawBitmap(drawingCache, 0, 0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int skipYear = 0;
|
private int skipYear = 0;
|
||||||
@@ -352,19 +379,19 @@ public class HabitScoreView extends ScrollableDataView implements HabitDataView
|
|||||||
setModeOrColor(pGraph, XFERMODE_CLEAR, backgroundColor);
|
setModeOrColor(pGraph, XFERMODE_CLEAR, backgroundColor);
|
||||||
canvas.drawOval(rect, pGraph);
|
canvas.drawOval(rect, pGraph);
|
||||||
|
|
||||||
if(isBackgroundTransparent)
|
if(isTransparencyEnabled)
|
||||||
pGraph.setXfermode(XFERMODE_SRC);
|
pGraph.setXfermode(XFERMODE_SRC);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIsBackgroundTransparent(boolean isBackgroundTransparent)
|
public void setIsTransparencyEnabled(boolean enabled)
|
||||||
{
|
{
|
||||||
this.isBackgroundTransparent = isBackgroundTransparent;
|
this.isTransparencyEnabled = enabled;
|
||||||
createColors();
|
createColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setModeOrColor(Paint p, PorterDuffXfermode mode, int color)
|
private void setModeOrColor(Paint p, PorterDuffXfermode mode, int color)
|
||||||
{
|
{
|
||||||
if(isBackgroundTransparent)
|
if(isTransparencyEnabled)
|
||||||
p.setXfermode(mode);
|
p.setXfermode(mode);
|
||||||
else
|
else
|
||||||
p.setColor(color);
|
p.setColor(color);
|
||||||
|
|||||||
@@ -21,8 +21,12 @@ package org.isoron.uhabits.views;
|
|||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.PorterDuff;
|
||||||
|
import android.graphics.PorterDuffXfermode;
|
||||||
import android.graphics.RectF;
|
import android.graphics.RectF;
|
||||||
import android.text.TextPaint;
|
import android.text.TextPaint;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
@@ -34,6 +38,9 @@ import org.isoron.uhabits.helpers.UIHelper;
|
|||||||
|
|
||||||
public class RingView extends View
|
public class RingView extends View
|
||||||
{
|
{
|
||||||
|
public static final PorterDuffXfermode XFERMODE_CLEAR =
|
||||||
|
new PorterDuffXfermode(PorterDuff.Mode.CLEAR);
|
||||||
|
|
||||||
private float precision;
|
private float precision;
|
||||||
private boolean enableFontAwesome;
|
private boolean enableFontAwesome;
|
||||||
|
|
||||||
@@ -43,9 +50,7 @@ public class RingView extends View
|
|||||||
private RectF rect;
|
private RectF rect;
|
||||||
|
|
||||||
private int diameter;
|
private int diameter;
|
||||||
|
|
||||||
private float textSize;
|
private float textSize;
|
||||||
|
|
||||||
private float thickness;
|
private float thickness;
|
||||||
|
|
||||||
private Integer backgroundColor;
|
private Integer backgroundColor;
|
||||||
@@ -53,6 +58,10 @@ public class RingView extends View
|
|||||||
private float em;
|
private float em;
|
||||||
private String text;
|
private String text;
|
||||||
|
|
||||||
|
private Bitmap drawingCache;
|
||||||
|
private Canvas cacheCanvas;
|
||||||
|
private boolean isTransparencyEnabled;
|
||||||
|
|
||||||
public RingView(Context context)
|
public RingView(Context context)
|
||||||
{
|
{
|
||||||
super(context);
|
super(context);
|
||||||
@@ -155,31 +164,68 @@ public class RingView extends View
|
|||||||
setMeasuredDimension(diameter, diameter);
|
setMeasuredDimension(diameter, diameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSizeChanged(int w, int h, int oldw, int oldh)
|
||||||
|
{
|
||||||
|
super.onSizeChanged(w, h, oldw, oldh);
|
||||||
|
|
||||||
|
if(isTransparencyEnabled)
|
||||||
|
{
|
||||||
|
if (drawingCache != null) drawingCache.recycle();
|
||||||
|
drawingCache = Bitmap.createBitmap(diameter, diameter, Bitmap.Config.ARGB_8888);
|
||||||
|
cacheCanvas = new Canvas(drawingCache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDraw(Canvas canvas)
|
protected void onDraw(Canvas canvas)
|
||||||
{
|
{
|
||||||
super.onDraw(canvas);
|
super.onDraw(canvas);
|
||||||
|
Canvas activeCanvas;
|
||||||
|
|
||||||
|
if(isTransparencyEnabled)
|
||||||
|
{
|
||||||
|
activeCanvas = cacheCanvas;
|
||||||
|
drawingCache.eraseColor(Color.TRANSPARENT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
activeCanvas = canvas;
|
||||||
|
}
|
||||||
|
|
||||||
pRing.setColor(color);
|
pRing.setColor(color);
|
||||||
rect.set(0, 0, diameter, diameter);
|
rect.set(0, 0, diameter, diameter);
|
||||||
|
|
||||||
float angle = 360 * Math.round(percentage / precision) * precision;
|
float angle = 360 * Math.round(percentage / precision) * precision;
|
||||||
|
|
||||||
canvas.drawArc(rect, -90, angle, true, pRing);
|
activeCanvas.drawArc(rect, -90, angle, true, pRing);
|
||||||
|
|
||||||
pRing.setColor(inactiveColor);
|
pRing.setColor(inactiveColor);
|
||||||
canvas.drawArc(rect, angle - 90, 360 - angle, true, pRing);
|
activeCanvas.drawArc(rect, angle - 90, 360 - angle, true, pRing);
|
||||||
|
|
||||||
if(thickness > 0)
|
if(thickness > 0)
|
||||||
{
|
{
|
||||||
pRing.setColor(backgroundColor);
|
if(isTransparencyEnabled)
|
||||||
|
pRing.setXfermode(XFERMODE_CLEAR);
|
||||||
|
else
|
||||||
|
pRing.setColor(backgroundColor);
|
||||||
|
|
||||||
rect.inset(thickness, thickness);
|
rect.inset(thickness, thickness);
|
||||||
canvas.drawArc(rect, 0, 360, true, pRing);
|
activeCanvas.drawArc(rect, 0, 360, true, pRing);
|
||||||
|
pRing.setXfermode(null);
|
||||||
|
|
||||||
pRing.setColor(color);
|
pRing.setColor(color);
|
||||||
pRing.setTextSize(textSize);
|
pRing.setTextSize(textSize);
|
||||||
if(enableFontAwesome) pRing.setTypeface(UIHelper.getFontAwesome(getContext()));
|
if(enableFontAwesome) pRing.setTypeface(UIHelper.getFontAwesome(getContext()));
|
||||||
canvas.drawText(text, rect.centerX(), rect.centerY() + 0.4f * em, pRing);
|
activeCanvas.drawText(text, rect.centerX(), rect.centerY() + 0.4f * em, pRing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(activeCanvas != canvas)
|
||||||
|
canvas.drawBitmap(drawingCache, 0, 0, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsTransparencyEnabled(boolean isTransparencyEnabled)
|
||||||
|
{
|
||||||
|
this.isTransparencyEnabled = isTransparencyEnabled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class ScoreWidgetProvider extends BaseWidgetProvider
|
|||||||
protected View buildCustomView(Context context, Habit habit)
|
protected View buildCustomView(Context context, Habit habit)
|
||||||
{
|
{
|
||||||
HabitScoreView dataView = new HabitScoreView(context);
|
HabitScoreView dataView = new HabitScoreView(context);
|
||||||
dataView.setIsBackgroundTransparent(true);
|
dataView.setIsTransparencyEnabled(true);
|
||||||
GraphWidgetView view = new GraphWidgetView(context, dataView);
|
GraphWidgetView view = new GraphWidgetView(context, dataView);
|
||||||
view.setHabit(habit);
|
view.setHabit(habit);
|
||||||
return view;
|
return view;
|
||||||
|
|||||||
Reference in New Issue
Block a user