diff --git a/spark/src/main/java/com/robinhood/spark/SparkView.java b/spark/src/main/java/com/robinhood/spark/SparkView.java index 4a92c0d..054bfaf 100644 --- a/spark/src/main/java/com/robinhood/spark/SparkView.java +++ b/spark/src/main/java/com/robinhood/spark/SparkView.java @@ -22,10 +22,13 @@ import android.content.res.TypedArray; import android.database.DataSetObserver; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.CornerPathEffect; +import android.graphics.LinearGradient; import android.graphics.Paint; import android.graphics.Path; import android.graphics.RectF; +import android.graphics.Shader; import android.os.Build; import android.os.Handler; import android.support.annotation.ColorInt; @@ -98,12 +101,15 @@ public class SparkView extends View implements ScrubGestureDetector.ScrubListene private float scrubLineWidth; private boolean scrubEnabled; private SparkAnimator sparkAnimator; + private float fadeLength; // the onDraw data private final Path renderPath = new Path(); private final Path sparkPath = new Path(); private final Path baseLinePath = new Path(); private final Path scrubLinePath = new Path(); + private final Path fadeLineLeftPath = new Path(); + private final Path fadeLineRightPath = new Path(); // adapter private SparkAdapter adapter; @@ -114,10 +120,13 @@ public class SparkView extends View implements ScrubGestureDetector.ScrubListene private Paint sparkFillPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private Paint baseLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG); private Paint scrubLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG); + private Paint fadeLineLeftPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + private Paint fadeLineRightPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private OnScrubListener scrubListener; private ScrubGestureDetector scrubGestureDetector; private Animator pathAnimator; private final RectF contentRect = new RectF(); + @ColorInt private int fadeColor; private List xPoints; private List yPoints; @@ -151,6 +160,7 @@ private void init(Context context, AttributeSet attrs, int defStyleAttr, int def fillColor = a.getColor(R.styleable.SparkView_spark_fillColor, 0); lineWidth = a.getDimension(R.styleable.SparkView_spark_lineWidth, 0); cornerRadius = a.getDimension(R.styleable.SparkView_spark_cornerRadius, 0); + fadeLength = a.getDimension(R.styleable.SparkView_spark_fadeLength, 0); // for backwards compatibility, set fill type based on spark_fill first, then overwrite if // new spark_fillType attribute is set @@ -190,6 +200,10 @@ private void init(Context context, AttributeSet attrs, int defStyleAttr, int def scrubLinePaint.setColor(scrubLineColor); scrubLinePaint.setStrokeCap(Paint.Cap.ROUND); + fadeLineLeftPaint.set(sparkLinePaint); + fadeLineRightPaint.set(sparkLinePaint); + fadeColor = Color.argb(0, Color.red(lineColor), Color.green(lineColor), Color.blue(lineColor)); + final Handler handler = new Handler(); final float touchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); scrubGestureDetector = new ScrubGestureDetector(this, handler, touchSlop); @@ -271,6 +285,21 @@ private void populatePath() { baseLinePath.lineTo(getWidth(), scaledBaseLine); } + fadeLineLeftPath.reset(); + fadeLineRightPath.reset(); + if(fadeLength > 0) { + final float firstY = scaleHelper.getY(adapter.getY(0)); + fadeLineLeftPath.moveTo(0, firstY); + fadeLineLeftPath.rLineTo(fadeLength, 0); + + final float lastY = scaleHelper.getY(adapter.getY(adapter.getCount() - 1)); + fadeLineRightPath.moveTo(contentRect.right, lastY); + fadeLineRightPath.rLineTo(fadeLength, 0); + + fadeLineLeftPaint.setShader(new LinearGradient(0,0, fadeLength, 0, fadeColor, lineColor, Shader.TileMode.CLAMP)); + fadeLineRightPaint.setShader(new LinearGradient(contentRect.right,0, contentRect.right + fadeLength, 0, lineColor, fadeColor, Shader.TileMode.CLAMP)); + } + renderPath.reset(); renderPath.addPath(sparkPath); @@ -391,6 +420,11 @@ protected void onDraw(Canvas canvas) { canvas.drawPath(renderPath, sparkLinePaint); canvas.drawPath(scrubLinePath, scrubLinePaint); + + if(fadeLength > 0) { + canvas.drawPath(fadeLineLeftPath, fadeLineLeftPaint); + canvas.drawPath(fadeLineRightPath, fadeLineRightPaint); + } } /** @@ -405,6 +439,7 @@ protected void onDraw(Canvas canvas) { */ public void setLineColor(@ColorInt int lineColor) { this.lineColor = lineColor; + this.fadeColor = Color.argb(0, Color.red(lineColor), Color.green(lineColor), Color.blue(lineColor)); sparkLinePaint.setColor(lineColor); invalidate(); } @@ -630,6 +665,15 @@ public void setBaseLinePaint(Paint baseLinePaint) { invalidate(); } + /** + * Set side fading amount, set 0 to disable fading + * @param length of faded line + */ + public void setFadeLength(float length) { + this.fadeLength = length; + invalidate(); + } + /** * Get the color of the scrub line */ @@ -842,9 +886,9 @@ private void updateContentRect() { if (contentRect == null) return; contentRect.set( - getPaddingStart(), + getPaddingStart() + fadeLength, getPaddingTop(), - getWidth() - getPaddingEnd(), + getWidth() - getPaddingEnd() - fadeLength, getHeight() - getPaddingBottom() ); } diff --git a/spark/src/main/res/values/attrs.xml b/spark/src/main/res/values/attrs.xml index 898ed0f..e3e15bb 100644 --- a/spark/src/main/res/values/attrs.xml +++ b/spark/src/main/res/values/attrs.xml @@ -25,6 +25,8 @@ + +