Android Custom drawable paint stroke different width -
i have issue when drawing path on drawable , setting drawable background or src of view/imageview. seems happening path on side arrow bit thicker straight lines... testing view has fixed dimensions. has ideas on how can fix it?
here drawable code.
public class arrowdrawable extends drawable { public static final string tag = arrowdrawable.class.getsimplename(); private paint outlinepaint; private paint fillpaint; int padding = 40; int arrowposition = 50; int arrowheight = 60; int strokewidth = 10; path path = new path(); public enum direction { right, left; } direction direction = direction.right; public arrowdrawable() { init(); } private void init() { outlinepaint = new paint(); outlinepaint.setstyle(paint.style.stroke); // set stoke outlinepaint.setstrokejoin(paint.join.bevel); // set join round want outlinepaint.setstrokecap(paint.cap.round); // set outlinepaint cap round outlinepaint.setpatheffect(new cornerpatheffect(2)); // set path effect when join. outlinepaint.setantialias(true); outlinepaint.setstrokewidth(strokewidth); fillpaint = new paint(paint.anti_alias_flag); fillpaint.setstrokewidth(strokewidth); fillpaint.setstrokejoin(paint.join.round); fillpaint.setpatheffect(new cornerpatheffect(2)); fillpaint.setstyle(paint.style.fill); fillpaint.setantialias(true); fillpaint.setcolor(color.white); } public void setdirection(direction direction) { this.direction = direction; invalidateself(); } public void setstrokecolor(int color) { outlinepaint.setcolor(color); invalidateself(); } public void setfillcolor(int color) { fillpaint.setcolor(color); invalidateself(); } public void setpadding(int padding) { this.padding = padding; invalidateself(); } public void setarrowposition(int arrowposition) { this.arrowposition = arrowposition; invalidateself(); } public void setarrowheight(int arrowheight) { this.arrowheight = arrowheight; invalidateself(); } public void setstrokewidth(int strokewidth) { this.strokewidth = strokewidth; invalidateself(); } @override public void draw(canvas canvas) { final rect bounds = getbounds(); log.d(tag, "draw: " + canvas.getwidth() + " " + canvas.getheight()); path path; if (direction == direction.right) { path = pointright(bounds); } else if (direction == direction.left) { path = pointleft(bounds); } else { throw new illegalargumentexception("direction not supported"); } path.computebounds(new rectf(bounds), false); canvas.drawpath(path, outlinepaint); } @override public void invalidateself() { path = null; super.invalidateself(); } @override protected void onboundschange(rect bounds) { super.onboundschange(bounds); invalidateself(); } public path pointright(rect bounds) { if (path != null) { return path; } final rect newrect = new rect(bounds.left, bounds.top, bounds.right - padding - strokewidth, bounds.bottom); path = new path(); path.moveto(newrect.left, newrect.top); path.lineto(newrect.right, newrect.top); path.lineto(newrect.right, newrect.top + arrowposition); path.lineto(bounds.right - strokewidth, newrect.top + arrowposition + arrowheight / 2.0f); path.lineto(newrect.right, newrect.top + arrowposition + arrowheight); path.lineto(newrect.right, newrect.bottom); path.lineto(newrect.left, newrect.bottom); path.close(); return path; } public path pointleft(rect bounds) { if (path != null) { return path; } final rect newrect = new rect(bounds.left + padding + strokewidth, bounds.top, bounds.right, bounds.bottom); path = new path(); path.moveto(newrect.left, newrect.top); path.lineto(newrect.left, newrect.top + arrowposition); path.lineto(bounds.left + strokewidth, newrect.top + arrowposition + arrowheight / 2.0f); path.lineto(newrect.left, newrect.top + arrowposition + arrowheight); path.lineto(newrect.left, newrect.bottom); path.lineto(newrect.right, newrect.bottom); path.lineto(newrect.right, newrect.top); path.close(); return path; } @override public void setalpha(int alpha) { } @override public void setcolorfilter(colorfilter colorfilter) { } @override public int getopacity() { return pixelformat.unknown; } }
so i've made work following drawable code. draws arrow outside of bounds. did on purpose don't have add paddings views put background. had set few flags on parent containers of views not clip background.
android:clipchildren="false" android:cliptopadding="false"
this seems working ok left , right arrow drawable.
public class arrowdrawable extends drawable { public static final string tag = arrowdrawable.class.getsimplename(); private paint outlinepaint; private paint fillpaint; private int padding = 40; private int arrowposition = 50; private int arrowheight = 60; private int strokewidth = 4; path path; public enum direction { right, left } direction direction = direction.right; public arrowdrawable() { init(); } private void init() { outlinepaint = new paint(); outlinepaint.setdither(true); // set dither true outlinepaint.setstyle(paint.style.stroke); // set stoke outlinepaint.setstrokejoin(paint.join.round); // set join round want outlinepaint.setstrokecap(paint.cap.round); // set outlinepaint cap round outlinepaint.setpatheffect(new cornerpatheffect(2)); // set path effect when join. outlinepaint.setantialias(true); fillpaint = new paint(paint.anti_alias_flag); fillpaint.setstrokejoin(paint.join.round); fillpaint.setpatheffect(new cornerpatheffect(2)); fillpaint.setstyle(paint.style.fill); fillpaint.setantialias(true); fillpaint.setcolor(color.transparent); } public void setdirection(direction direction) { this.direction = direction; invalidateself(); } public void setstrokecolor(int color) { outlinepaint.setcolor(color); invalidateself(); } public void setfillcolor(int color) { fillpaint.setcolor(color); invalidateself(); } public void setpadding(int padding) { this.padding = padding; invalidateself(); } public void setarrowposition(int arrowposition) { this.arrowposition = arrowposition; invalidateself(); } public void setarrowheight(int arrowheight) { this.arrowheight = arrowheight; invalidateself(); } public void setstrokewidth(int strokewidth) { this.strokewidth = strokewidth; invalidateself(); } @override protected void onboundschange(rect bounds) { super.onboundschange(bounds); recalculatepath(bounds); } private void recalculatepath(rect bounds) { if (direction == direction.right) { path = pointright(bounds); } else if (direction == direction.left) { path = pointleft(bounds); } else { throw new illegalargumentexception("direction not supported"); } } @override public void draw(canvas canvas) { if (path == null) { return; } outlinepaint.setstrokewidth(strokewidth); fillpaint.setstrokewidth(strokewidth); canvas.drawpath(path, fillpaint); canvas.drawpath(path, outlinepaint); } @override public void invalidateself() { recalculatepath(getbounds()); super.invalidateself(); } public path pointright(rect bounds) { final rect newrect = new rect(bounds.left, bounds.top, bounds.right, bounds.bottom); path = new path(); path.moveto(newrect.left, newrect.top); path.lineto(newrect.right, newrect.top); path.lineto(newrect.right, newrect.top + arrowposition); path.lineto(bounds.right + padding - strokewidth, newrect.top + arrowposition + arrowheight / 2.0f); path.lineto(newrect.right, newrect.top + arrowposition + arrowheight); path.lineto(newrect.right, newrect.bottom); path.lineto(newrect.left, newrect.bottom); path.close(); return path; } public path pointleft(rect bounds) { final rect newrect = new rect(bounds.left, bounds.top, bounds.right, bounds.bottom); path = new path(); path.moveto(newrect.left, newrect.top); path.lineto(newrect.left, newrect.top + arrowposition); path.lineto(bounds.left - padding + strokewidth, newrect.top + arrowposition + arrowheight / 2.0f); path.lineto(newrect.left, newrect.top + arrowposition + arrowheight); path.lineto(newrect.left, newrect.bottom); path.lineto(newrect.right, newrect.bottom); path.lineto(newrect.right, newrect.top); path.close(); return path; } @override public void setalpha(int alpha) { } @override public void setcolorfilter(colorfilter colorfilter) { } @override public int getopacity() { return pixelformat.unknown; } }
Comments
Post a Comment