From 2dc4fcbc467ffbbd6d58825fe715a2fc8bcf6ea5 Mon Sep 17 00:00:00 2001 From: Alinson Xavier Date: Mon, 25 Apr 2016 22:22:37 -0400 Subject: [PATCH] Fix transparency on widgets --- .../unit/views/HabitScoreViewTest.java | 2 +- .../uhabits/views/CheckmarkWidgetView.java | 2 + .../isoron/uhabits/views/HabitScoreView.java | 47 +++++++++++---- .../org/isoron/uhabits/views/RingView.java | 60 ++++++++++++++++--- .../uhabits/widgets/ScoreWidgetProvider.java | 2 +- 5 files changed, 94 insertions(+), 19 deletions(-) diff --git a/app/src/androidTest/java/org/isoron/uhabits/unit/views/HabitScoreViewTest.java b/app/src/androidTest/java/org/isoron/uhabits/unit/views/HabitScoreViewTest.java index 3dd19bb4d..a7f1228b9 100644 --- a/app/src/androidTest/java/org/isoron/uhabits/unit/views/HabitScoreViewTest.java +++ b/app/src/androidTest/java/org/isoron/uhabits/unit/views/HabitScoreViewTest.java @@ -62,7 +62,7 @@ public class HabitScoreViewTest extends ViewTest @Test public void testRender_withTransparentBackground() throws Throwable { - view.setIsBackgroundTransparent(true); + view.setIsTransparencyEnabled(true); assertRenders(view, "HabitScoreView/renderTransparent.png"); } diff --git a/app/src/main/java/org/isoron/uhabits/views/CheckmarkWidgetView.java b/app/src/main/java/org/isoron/uhabits/views/CheckmarkWidgetView.java index 2d8525753..5d0e5c7e0 100644 --- a/app/src/main/java/org/isoron/uhabits/views/CheckmarkWidgetView.java +++ b/app/src/main/java/org/isoron/uhabits/views/CheckmarkWidgetView.java @@ -62,6 +62,8 @@ public class CheckmarkWidgetView extends HabitWidgetView implements HabitDataVie ring = (RingView) findViewById(R.id.scoreRing); label = (TextView) findViewById(R.id.label); + if(ring != null) ring.setIsTransparencyEnabled(true); + if(isInEditMode()) { percentage = 0.75f; diff --git a/app/src/main/java/org/isoron/uhabits/views/HabitScoreView.java b/app/src/main/java/org/isoron/uhabits/views/HabitScoreView.java index a47248a25..6702cf581 100644 --- a/app/src/main/java/org/isoron/uhabits/views/HabitScoreView.java +++ b/app/src/main/java/org/isoron/uhabits/views/HabitScoreView.java @@ -20,7 +20,9 @@ package org.isoron.uhabits.views; import android.content.Context; +import android.graphics.Bitmap; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; @@ -71,11 +73,14 @@ public class HabitScoreView extends ScrollableDataView implements HabitDataView private int[] scores; private int primaryColor; - private boolean isBackgroundTransparent; private int bucketSize = 7; private int footerHeight; private int backgroundColor; + private Bitmap drawingCache; + private Canvas cacheCanvas; + private boolean isTransparencyEnabled; + public HabitScoreView(Context context) { super(context); @@ -168,6 +173,13 @@ public class HabitScoreView extends ScrollableDataView implements HabitDataView pGraph.setTextSize(baseSize * 0.5f); pGraph.setStrokeWidth(baseSize * 0.1f); 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() @@ -206,12 +218,24 @@ public class HabitScoreView extends ScrollableDataView implements HabitDataView protected void onDraw(Canvas canvas) { super.onDraw(canvas); + Canvas activeCanvas; + + if(isTransparencyEnabled) + { + activeCanvas = cacheCanvas; + drawingCache.eraseColor(Color.TRANSPARENT); + } + else + { + activeCanvas = canvas; + } + if (habit == null || scores == null) return; rect.set(0, 0, nColumns * columnWidth, columnHeight); rect.offset(0, paddingTop); - drawGrid(canvas, rect); + drawGrid(activeCanvas, rect); pText.setColor(textColor); pGraph.setColor(primaryColor); @@ -241,20 +265,23 @@ public class HabitScoreView extends ScrollableDataView implements HabitDataView if (!prevRect.isEmpty()) { - drawLine(canvas, prevRect, rect); - drawMarker(canvas, prevRect); + drawLine(activeCanvas, prevRect, rect); + drawMarker(activeCanvas, prevRect); } - if (k == nColumns - 1) drawMarker(canvas, rect); + if (k == nColumns - 1) drawMarker(activeCanvas, rect); prevRect.set(rect); rect.set(0, 0, columnWidth, columnHeight); rect.offset(k * columnWidth, paddingTop); - drawFooter(canvas, rect, currentDate); + drawFooter(activeCanvas, rect, currentDate); currentDate += bucketSize * DateHelper.millisecondsInOneDay; } + + if(activeCanvas != canvas) + canvas.drawBitmap(drawingCache, 0, 0, null); } private int skipYear = 0; @@ -352,19 +379,19 @@ public class HabitScoreView extends ScrollableDataView implements HabitDataView setModeOrColor(pGraph, XFERMODE_CLEAR, backgroundColor); canvas.drawOval(rect, pGraph); - if(isBackgroundTransparent) + if(isTransparencyEnabled) pGraph.setXfermode(XFERMODE_SRC); } - public void setIsBackgroundTransparent(boolean isBackgroundTransparent) + public void setIsTransparencyEnabled(boolean enabled) { - this.isBackgroundTransparent = isBackgroundTransparent; + this.isTransparencyEnabled = enabled; createColors(); } private void setModeOrColor(Paint p, PorterDuffXfermode mode, int color) { - if(isBackgroundTransparent) + if(isTransparencyEnabled) p.setXfermode(mode); else p.setColor(color); 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 0462feb83..942ba4a9a 100644 --- a/app/src/main/java/org/isoron/uhabits/views/RingView.java +++ b/app/src/main/java/org/isoron/uhabits/views/RingView.java @@ -21,8 +21,12 @@ package org.isoron.uhabits.views; import android.annotation.SuppressLint; import android.content.Context; +import android.graphics.Bitmap; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; import android.graphics.RectF; import android.text.TextPaint; import android.util.AttributeSet; @@ -34,6 +38,9 @@ import org.isoron.uhabits.helpers.UIHelper; public class RingView extends View { + public static final PorterDuffXfermode XFERMODE_CLEAR = + new PorterDuffXfermode(PorterDuff.Mode.CLEAR); + private float precision; private boolean enableFontAwesome; @@ -43,9 +50,7 @@ public class RingView extends View private RectF rect; private int diameter; - private float textSize; - private float thickness; private Integer backgroundColor; @@ -53,6 +58,10 @@ public class RingView extends View private float em; private String text; + private Bitmap drawingCache; + private Canvas cacheCanvas; + private boolean isTransparencyEnabled; + public RingView(Context context) { super(context); @@ -155,31 +164,68 @@ public class RingView extends View 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 protected void onDraw(Canvas canvas) { super.onDraw(canvas); + Canvas activeCanvas; + + if(isTransparencyEnabled) + { + activeCanvas = cacheCanvas; + drawingCache.eraseColor(Color.TRANSPARENT); + } + else + { + activeCanvas = canvas; + } pRing.setColor(color); rect.set(0, 0, diameter, diameter); 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); - canvas.drawArc(rect, angle - 90, 360 - angle, true, pRing); + activeCanvas.drawArc(rect, angle - 90, 360 - angle, true, pRing); if(thickness > 0) { - pRing.setColor(backgroundColor); + if(isTransparencyEnabled) + pRing.setXfermode(XFERMODE_CLEAR); + else + pRing.setColor(backgroundColor); + 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.setTextSize(textSize); 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; } } diff --git a/app/src/main/java/org/isoron/uhabits/widgets/ScoreWidgetProvider.java b/app/src/main/java/org/isoron/uhabits/widgets/ScoreWidgetProvider.java index d478838be..0e43a60c1 100644 --- a/app/src/main/java/org/isoron/uhabits/widgets/ScoreWidgetProvider.java +++ b/app/src/main/java/org/isoron/uhabits/widgets/ScoreWidgetProvider.java @@ -35,7 +35,7 @@ public class ScoreWidgetProvider extends BaseWidgetProvider protected View buildCustomView(Context context, Habit habit) { HabitScoreView dataView = new HabitScoreView(context); - dataView.setIsBackgroundTransparent(true); + dataView.setIsTransparencyEnabled(true); GraphWidgetView view = new GraphWidgetView(context, dataView); view.setHabit(habit); return view;