下面列出了android.graphics.Path#lineTo ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* 画指示器
*
* @param canvas
*/
private void drawIndicator(Canvas canvas) {
PathMeasure mPathMeasure = new PathMeasure();
mPathMeasure.setPath(mArcPath, false);
float[] tan = new float[2];
float[] pos = new float[2];
mPathMeasure.getPosTan(mPathMeasure.getLength() * (0.5f), pos, tan);
canvas.save();
double angle = calcArcAngle(Math.atan2(tan[1], tan[0])) + 90;
canvas.rotate((float) angle, pos[0], pos[1]);
//画直线
canvas.drawLine(pos[0], pos[1], pos[0] + 80, pos[1], mIndicatorPaint);
Path linePath = new Path();
//画箭头
linePath.moveTo(pos[0] + 80, pos[1] - 20);
linePath.lineTo(pos[0] + 80 + 20, pos[1]);
linePath.lineTo(pos[0] + 80, pos[1] + 20);
canvas.drawPath(linePath, mIndicatorPaint);
canvas.restore();
}
private void drawIndicator() {
float xPos = x + (getNearestDeviation() * gaugeWidth / MAX_DEVIATION);
float yPosition = y * 1.15f;
Matrix matrix = new Matrix();
float scalingFactor = numbersPaint.getTextSize() / 3;
matrix.setScale(scalingFactor, scalingFactor);
Path indicator = new Path();
indicator.moveTo(0, -2);
indicator.lineTo(1, 0);
indicator.lineTo(-1, 0);
indicator.close();
indicator.transform(matrix);
indicator.offset(xPos, yPosition);
canvas.drawPath(indicator, gaugePaint);
}
@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
TypedValue value = new TypedValue();
getContext().getTheme()
.resolveAttribute(R.attr.wizardBackgroundBottom, value, true);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.FILL);
paint.setColor(getContext().getResources()
.getColor(value.resourceId));
path = new Path();
float horizontalOffset = w * .8f;
float top = -h * .8f;
float bottom = h;
RectF ovalRect = new RectF(-horizontalOffset, top, w + horizontalOffset, bottom);
path.lineTo(ovalRect.left, top);
path.arcTo(ovalRect, 0, 300, false);
path.setFillType(Path.FillType.INVERSE_EVEN_ODD);
}
private Path getActionPath(float curPercent) {
final Path path = new Path();
int x = -mDisplayWidth;
x += curPercent * mDisplayWidth;
path.moveTo(x, mDisplayHeight / 2);
// 计算控制点
int quadWidth = mDisplayWidth / 4;
int quadHeight = mDisplayHeight / 20 * 3;
// 第一个周期
path.rQuadTo(quadWidth, quadHeight, quadWidth * 2, 0);
path.rQuadTo(quadWidth, -quadHeight, quadWidth * 2, 0);
// 第二个周期
path.rQuadTo(quadWidth, quadHeight, quadWidth * 2, 0);
path.rQuadTo(quadWidth, -quadHeight, quadWidth * 2, 0);
// 右侧的直线
path.lineTo(x + mDisplayWidth * 2, mDisplayHeight);
path.lineTo(x, mDisplayHeight);
path.close();
return path;
}
private void setUpTopPath(RectF rect, Path path) {
if (mArrowCenter) {
mArrowPosition = (rect.right - rect.left) / 2 - mArrowWidth / 2;
}
path.moveTo(rect.left + Math.min(mArrowPosition, mAngle), rect.top + mArrowHeight);
path.lineTo(rect.left + mArrowPosition, rect.top + mArrowHeight);
path.lineTo(rect.left + mArrowWidth / 2 + mArrowPosition, rect.top);
path.lineTo(rect.left + mArrowWidth + mArrowPosition, rect.top + mArrowHeight);
path.lineTo(rect.right - mAngle, rect.top + mArrowHeight);
path.arcTo(new RectF(rect.right - mAngle,
rect.top + mArrowHeight, rect.right, mAngle + rect.top + mArrowHeight), 270, 90);
path.lineTo(rect.right, rect.bottom - mAngle);
path.arcTo(new RectF(rect.right - mAngle, rect.bottom - mAngle,
rect.right, rect.bottom), 0, 90);
path.lineTo(rect.left + mAngle, rect.bottom);
path.arcTo(new RectF(rect.left, rect.bottom - mAngle,
mAngle + rect.left, rect.bottom), 90, 90);
path.lineTo(rect.left, rect.top + mArrowHeight + mAngle);
path.arcTo(new RectF(rect.left, rect.top + mArrowHeight, mAngle
+ rect.left, mAngle + rect.top + mArrowHeight), 180, 90);
path.close();
}
private void drawTriangle(Canvas canvas) {
Path p = new Path();
if (rotate_degree >= 0 && rotate_degree < 30) {
first_pointX = radius - triangle_length * Math.abs(Math.cos(Math.PI / 3 + rotate_degree * Math.PI / 180) * Math.sqrt(3) / 3);
first_pointY = radius - triangle_length * Math.abs(Math.sin(Math.PI / 3 + rotate_degree * Math.PI / 180) * Math.sqrt(3) / 3);
} else if (rotate_degree >= 30 && rotate_degree <= 120) {
first_pointX = radius + triangle_length * Math.abs(Math.cos(Math.PI / 3 + rotate_degree * Math.PI / 180) * Math.sqrt(3) / 3);
first_pointY = radius - triangle_length * Math.abs(Math.sin(Math.PI / 3 + rotate_degree * Math.PI / 180) * Math.sqrt(3) / 3);
}
if (rotate_degree >= 0 && rotate_degree < 90) {
second_pointX = radius + triangle_length * Math.abs(Math.cos(rotate_degree * Math.PI / 180) * Math.sqrt(3) / 3);
second_pointY = radius + triangle_length * Math.abs(Math.sin(rotate_degree * Math.PI / 180) * Math.sqrt(3) / 3);
} else if (rotate_degree > 90 && rotate_degree <= 120) {
second_pointX = radius - triangle_length * Math.abs(Math.cos(rotate_degree * Math.PI / 180) * Math.sqrt(3) / 3);
second_pointY = radius + triangle_length * Math.abs(Math.sin(rotate_degree * Math.PI / 180) * Math.sqrt(3) / 3);
}
if (rotate_degree >= 0 && rotate_degree < 60) {
third_pointX = radius - triangle_length * Math.abs(Math.cos(Math.PI / 3 - rotate_degree * Math.PI / 180) * Math.sqrt(3) / 3);
third_pointY = radius + triangle_length * Math.abs(Math.sin(Math.PI / 3 - rotate_degree * Math.PI / 180) * Math.sqrt(3) / 3);
} else if (rotate_degree >= 60 && rotate_degree <= 120) {
third_pointX = radius - triangle_length * Math.abs(Math.cos(Math.PI / 3 - rotate_degree * Math.PI / 180) * Math.sqrt(3) / 3);
third_pointY = radius - triangle_length * Math.abs(Math.sin(Math.PI / 3 - rotate_degree * Math.PI / 180) * Math.sqrt(3) / 3);
}
p.moveTo((float) first_pointX, (float) first_pointY);
p.lineTo((float) second_pointX, (float) second_pointY);
p.lineTo((float) third_pointX, (float) third_pointY);
p.close();
canvas.drawPath(p, mTrianglePaint);
redrawTriangle();
}
/**
* Generates a path that is used for filled drawing.
*
* @param dataSet The dataset from which to read the entries.
* @param startIndex The index from which to start reading the dataset
* @param endIndex The index from which to stop reading the dataset
* @param outputPath The path object that will be assigned the chart data.
* @return
*/
private void generateFilledPath(final ILineDataSet dataSet, final int startIndex, final int endIndex, final Path outputPath) {
final float fillMin = dataSet.getFillFormatter().getFillLinePosition(dataSet, mChart);
final float phaseY = mAnimator.getPhaseY();
final boolean isDrawSteppedEnabled = dataSet.getMode() == LineDataSet.Mode.STEPPED;
final Path filled = outputPath;
filled.reset();
final Entry entry = dataSet.getEntryForIndex(startIndex);
filled.moveTo(entry.getX(), fillMin);
filled.lineTo(entry.getX(), entry.getY() * phaseY);
// create a new path
Entry currentEntry = null;
Entry previousEntry = null;
for (int x = startIndex + 1; x <= endIndex; x++) {
currentEntry = dataSet.getEntryForIndex(x);
if (isDrawSteppedEnabled && previousEntry != null) {
filled.lineTo(currentEntry.getX(), previousEntry.getY() * phaseY);
}
filled.lineTo(currentEntry.getX(), currentEntry.getY() * phaseY);
previousEntry = currentEntry;
}
// close up
if (currentEntry != null) {
filled.lineTo(currentEntry.getX(), fillMin);
}
filled.close();
}
private void drawDocumentBox(Point[] points, Size stdSize) {
Path path = new Path();
HUDCanvasView hud = mMainActivity.getHUD();
// ATTENTION: axis are swapped
float previewWidth = (float) stdSize.height;
float previewHeight = (float) stdSize.width;
path.moveTo( previewWidth - (float) points[0].y, (float) points[0].x );
path.lineTo( previewWidth - (float) points[1].y, (float) points[1].x );
path.lineTo( previewWidth - (float) points[2].y, (float) points[2].x );
path.lineTo( previewWidth - (float) points[3].y, (float) points[3].x );
path.close();
PathShape newBox = new PathShape(path , previewWidth , previewHeight);
Paint paint = new Paint();
paint.setColor(Color.argb(64, 0, 255, 0));
Paint border = new Paint();
border.setColor(Color.rgb(0, 255, 0));
border.setStrokeWidth(5);
hud.clear();
hud.addShape(newBox, paint, border);
mMainActivity.invalidateHUD();
}
private void drawLiftUp(Canvas canvas) {
Path path = new Path();
path.moveTo(0, roundHeight);
path.lineTo(0, 0);
path.lineTo(roundWidth, 0);
path.arcTo(new RectF(0, 0, roundWidth * 2, roundHeight * 2), -90, -90);
path.close();
canvas.drawPath(path, paint);
}
private static Path getTrianglePath(Point p1, int width) {
Point p2 = new Point(p1.x + width, p1.y);
Point p3 = new Point(p1.x, p1.y + width);
Path path = new Path();
path.moveTo(p1.x, p1.y);
path.lineTo(p2.x, p2.y);
path.lineTo(p3.x, p3.y);
return path;
}
protected Path drawSolidEdgingLine(float scaledWidth, GeoLineString lineString, GISDisplay display) {
Paint mainPaint = new Paint();
mainPaint.setColor(mColor);
mainPaint.setAntiAlias(true);
mainPaint.setStyle(Paint.Style.STROKE);
mainPaint.setStrokeCap(Paint.Cap.BUTT);
mainPaint.setStrokeWidth(scaledWidth);
Paint edgingPaint = new Paint(mainPaint);
edgingPaint.setColor(mOutColor);
edgingPaint.setStrokeCap(Paint.Cap.BUTT);
edgingPaint.setStrokeWidth(scaledWidth * 3);
List<GeoPoint> points = lineString.getPoints();
Path path = new Path();
path.incReserve(points.size());
path.moveTo((float) points.get(0).getX(), (float) points.get(0).getY());
for (int i = 1; i < points.size(); ++i) {
path.lineTo((float) points.get(i).getX(), (float) points.get(i).getY());
}
display.drawPath(path, edgingPaint);
display.drawPath(path, mainPaint);
return path;
}
@Override
public void renderGridLines(Canvas c) {
if (!mYAxis.isEnabled())
return;
// pre alloc
float[] position = new float[2];
if (mYAxis.isDrawGridLinesEnabled()) {
mGridPaint.setColor(mYAxis.getGridColor());
mGridPaint.setStrokeWidth(mYAxis.getGridLineWidth());
mGridPaint.setPathEffect(mYAxis.getGridDashPathEffect());
Path gridLinePath = new Path();
// draw the horizontal grid
for (int i = 0; i < mYAxis.mEntryCount; i++) {
position[1] = mYAxis.mEntries[i];
mTrans.pointValuesToPixel(position);
gridLinePath.moveTo(mViewPortHandler.offsetLeft(), position[1]);
gridLinePath.lineTo(mViewPortHandler.contentRight(), position[1]);
// draw a path because lines don't support dashing on lower android versions
c.drawPath(gridLinePath, mGridPaint);
gridLinePath.reset();
}
}
if (mYAxis.isDrawZeroLineEnabled()) {
// draw zero line
position[1] = 0f;
mTrans.pointValuesToPixel(position);
drawZeroLine(c, mViewPortHandler.offsetLeft(), mViewPortHandler.contentRight(), position[1] - 1, position[1] - 1);
}
}
/**
* Draws the RadarDataSet
*
* @param c
* @param dataSet
* @param mostEntries the entry count of the dataset with the most entries
*/
protected void drawDataSet(Canvas c, IRadarDataSet dataSet, int mostEntries) {
float phaseX = mAnimator.getPhaseX();
float phaseY = mAnimator.getPhaseY();
float sliceangle = mChart.getSliceAngle();
// calculate the factor that is needed for transforming the value to
// pixels
float factor = mChart.getFactor();
PointF center = mChart.getCenterOffsets();
Path surface = new Path();
boolean hasMovedToPoint = false;
for (int j = 0; j < dataSet.getEntryCount(); j++) {
mRenderPaint.setColor(dataSet.getColor(j));
Entry e = dataSet.getEntryForIndex(j);
PointF p = Utils.getPosition(
center,
(e.getVal() - mChart.getYChartMin()) * factor * phaseY,
sliceangle * j * phaseX + mChart.getRotationAngle());
if (Float.isNaN(p.x))
continue;
if (!hasMovedToPoint) {
surface.moveTo(p.x, p.y);
hasMovedToPoint = true;
} else
surface.lineTo(p.x, p.y);
}
// if this is the largest set, close it
if (dataSet.getEntryCount() >= mostEntries) {
surface.close();
} else {
// if this is not the largest set, draw a line to the center and then close it
surface.lineTo(center.x, center.y);
surface.close();
}
if(dataSet.isDrawFilledEnabled()) {
final Drawable drawable = dataSet.getFillDrawable();
if (drawable != null) {
drawFilledPath(c, surface, drawable);
} else {
drawFilledPath(c, surface, dataSet.getFillColor(), dataSet.getFillAlpha());
}
}
mRenderPaint.setStrokeWidth(dataSet.getLineWidth());
mRenderPaint.setStyle(Paint.Style.STROKE);
// draw the line (only if filled is disabled or alpha is below 255)
if (!dataSet.isDrawFilledEnabled() || dataSet.getFillAlpha() < 255)
c.drawPath(surface, mRenderPaint);
//
// // draw filled
// if (dataSet.isDrawFilledEnabled()) {
// mRenderPaint.setStyle(Paint.Style.FILL);
// mRenderPaint.setAlpha(dataSet.getFillAlpha());
// c.drawPath(surface, mRenderPaint);
// mRenderPaint.setAlpha(255);
// }
}
@Override
public void drawHighlighted(Canvas c, Highlight[] indices) {
BarData barData = mChart.getBarData();
int setCount = barData.getDataSetCount();
for (Highlight high : indices) {
final int minDataSetIndex = high.getDataSetIndex() == -1
? 0
: high.getDataSetIndex();
final int maxDataSetIndex = high.getDataSetIndex() == -1
? barData.getDataSetCount()
: (high.getDataSetIndex() + 1);
if (maxDataSetIndex - minDataSetIndex < 1) continue;
for (int dataSetIndex = minDataSetIndex;
dataSetIndex < maxDataSetIndex;
dataSetIndex++) {
IBarDataSet set = barData.getDataSetByIndex(dataSetIndex);
if (set == null || !set.isHighlightEnabled())
continue;
float barspaceHalf = set.getBarSpace() / 2f;
Transformer trans = mChart.getTransformer(set.getAxisDependency());
mHighlightPaint.setColor(set.getHighLightColor());
mHighlightPaint.setAlpha(set.getHighLightAlpha());
int index = high.getXIndex();
// check outofbounds
if (index >= 0
&& index < (mChart.getXChartMax() * mAnimator.getPhaseX()) / setCount) {
BarEntry e = set.getEntryForXIndex(index);
if (e == null || e.getXIndex() != index)
continue;
float groupspace = barData.getGroupSpace();
boolean isStack = high.getStackIndex() < 0 ? false : true;
// calculate the correct x-position
float x = index * setCount + dataSetIndex + groupspace / 2f
+ groupspace * index;
final float y1;
final float y2;
if (isStack) {
y1 = high.getRange().from;
y2 = high.getRange().to;
} else {
y1 = e.getVal();
y2 = 0.f;
}
prepareBarHighlight(x, y1, y2, barspaceHalf, trans);
c.drawRect(mBarRect, mHighlightPaint);
if (mChart.isDrawHighlightArrowEnabled()) {
mHighlightPaint.setAlpha(255);
// distance between highlight arrow and bar
float offsetY = mAnimator.getPhaseY() * 0.07f;
float[] values = new float[9];
trans.getPixelToValueMatrix().getValues(values);
final float xToYRel = Math.abs(
values[Matrix.MSCALE_Y] / values[Matrix.MSCALE_X]);
final float arrowWidth = set.getBarSpace() / 2.f;
final float arrowHeight = arrowWidth * xToYRel;
final float yArrow = (y1 > -y2 ? y1 : y1) * mAnimator.getPhaseY();
Path arrow = new Path();
arrow.moveTo(x + 0.4f, yArrow + offsetY);
arrow.lineTo(x + 0.4f + arrowWidth, yArrow + offsetY - arrowHeight);
arrow.lineTo(x + 0.4f + arrowWidth, yArrow + offsetY + arrowHeight);
trans.pathValueToPixel(arrow);
c.drawPath(arrow, mHighlightPaint);
}
}
}
}
}
private void createFlash(int x1, int y1) {
flash1 = new Path();
flash2 = new Path();
flash3 = new Path();
flash1.moveTo(x1, y1);
flash2.moveTo(x1, y1);
flash3.moveTo(x1, y1);
int[] yArray = randomArray(0, 400, 50);
Arrays.sort(yArray);
int[] xArray = new int[yArray.length];
for (int i = 0; i < yArray.length; i++) {
xArray[i] = (int) (yArray[i] + (16 - (Math.random() * 32)));
flash1.lineTo(xArray[i] + x1, yArray[i] + y1);
}
flashPathMeasure1.setPath(flash1, false);
mFlashLength1 = flashPathMeasure1.getLength();
int[] yArray2Temp = randomArray(yArray[20], yArray[40], 20);
Arrays.sort(yArray2Temp);
int[] xArray2Temp = new int[yArray2Temp.length];
for (int i = 0; i < yArray2Temp.length; i++) {
xArray2Temp[i] = (int) (yArray2Temp[i] * 0.5f + (16 - (Math.random() * 32)));
}
int[] xArray2 = new int[xArray2Temp.length + 11];
System.arraycopy(xArray, 0, xArray2, 0, 11);
System.arraycopy(xArray2Temp, 0, xArray2, 11, xArray2Temp.length);
int[] yArray2 = new int[yArray2Temp.length + 11];
System.arraycopy(yArray, 0, yArray2, 0, 11);
System.arraycopy(yArray2Temp, 0, yArray2, 11, yArray2Temp.length);
int[] yArray3Temp = randomArray(yArray[25], yArray[45], 20);
Arrays.sort(yArray3Temp);
int[] xArray3Temp = new int[yArray3Temp.length];
for (int i = 0; i < yArray3Temp.length; i++) {
xArray3Temp[i] = (int) (yArray3Temp[i] * 1.5f + (16 - (Math.random() * 32)));
}
int[] xArray3 = new int[xArray3Temp.length + 26];
System.arraycopy(xArray, 0, xArray3, 0, 26);
System.arraycopy(xArray3Temp, 0, xArray3, 26, xArray3Temp.length);
int[] yArray3 = new int[yArray3Temp.length + 26];
System.arraycopy(yArray, 0, yArray3, 0, 26);
System.arraycopy(yArray3Temp, 0, yArray3, 26, yArray3Temp.length);
for (int m = 0; m < xArray2.length; m++) {
flash2.lineTo(xArray2[m] + x1, yArray2[m] + y1);
}
for (int n = 0; n < xArray3.length; n++) {
flash3.lineTo(xArray3[n] + x1, yArray3[n] + y1);
}
flashPathMeasure2.setPath(flash2, false);
mFlashLength2 = flashPathMeasure2.getLength();
flashPathMeasure3.setPath(flash3, false);
mFlashLength3 = flashPathMeasure3.getLength();
}
private Path getModeRightPath(Path path, int w, int h) {
path.lineTo(w, h);
path.lineTo(w, h - mSlantedLength);
path.lineTo(mSlantedLength, 0);
return path;
}
public void draw(Canvas canvas)
{
// various dimensions and colors
int size = 28;
int hightlightBorderWidth = Math.max(1, pageToView(5));
int highlightBorderColor = Color.parseColor("#0080FF");
int highlightColor = Color.parseColor("#0080FF");
int highlightAlpha = 50;
int bubbleBorderColor = Color.parseColor("#000000");
int bubbleBorderWidth = Math.max(1, pageToView(1));
int bubbleColor = Color.parseColor("#FFFF00");
int bubbleAlpha = 128;
int cornerRadius = pageToView(4);
// get the rect in view coordinates
PointF ul = new PointF(mPoint.x, mPoint.y-size);
PointF dr = new PointF(mPoint.x+size, mPoint.y);
pageToView(ul, ul);
pageToView(dr, dr);
Rect rt = new Rect((int)ul.x, (int)ul.y, (int)dr.x, (int)dr.y);
if (isSelected())
{
// paint a selection highligt
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setAlpha(255);
paint.setColor(highlightBorderColor);
paint.setStrokeWidth(hightlightBorderWidth);
canvas.drawRect(rt, paint);
paint.setStyle(Paint.Style.FILL);
paint.setColor(highlightColor);
paint.setAlpha(highlightAlpha);
canvas.drawRect(rt, paint);
}
// create a path for the bubble
Path path = new Path();
path.moveTo(rt.left, rt.bottom-cornerRadius);
path.lineTo(rt.left, rt.top+cornerRadius);
final RectF oval = new RectF();
oval.set(rt.left, rt.top, rt.left+2*cornerRadius, rt.top+2*cornerRadius);
path.arcTo(oval, 180, 90);
path.lineTo(rt.right-cornerRadius, rt.top);
oval.set(rt.right-2*cornerRadius, rt.top, rt.right, rt.top+2*cornerRadius);
path.arcTo(oval, 270, 90);
path.lineTo(rt.right, rt.bottom-cornerRadius);
oval.set(rt.right-2*cornerRadius, rt.bottom-2*cornerRadius, rt.right, rt.bottom);
path.arcTo(oval, 0, 90);
path.lineTo(rt.left+3*cornerRadius, rt.bottom);
path.lineTo(rt.left, rt.bottom+rt.height()/3);
path.lineTo(rt.left+cornerRadius, rt.bottom);
oval.set(rt.left, rt.bottom-2*cornerRadius, rt.left+2*cornerRadius, rt.bottom);
path.arcTo(oval, 90, 90);
path.lineTo(rt.left, rt.bottom-cornerRadius);
path.close();
// paint the bubble interior
Paint p1 = new Paint();
p1.setStyle(Paint.Style.FILL);
p1.setColor(bubbleColor);
p1.setAlpha(bubbleAlpha);
canvas.drawPath(path, p1);
// paint the bubble border
Paint p2 = new Paint();
p2.setStyle(Paint.Style.STROKE);
p2.setColor(bubbleBorderColor);
p2.setStrokeWidth(bubbleBorderWidth);
canvas.drawPath(path, p2);
}
private static void endBorder(Path path, float inset, float edgeLen, float cornerRadius, float cornerSweepAngle) {
cornerArc(path, inset, edgeLen, cornerRadius - inset, 90 - cornerSweepAngle, cornerSweepAngle);
path.lineTo(inset, inset);
path.close();
}
private Path getModeRightTrianglePath(Path path, int w, int h) {
path.lineTo(w,0);
path.lineTo(w,h);
return path;
}
protected Path drawDashLine(float scaledWidth, GeoLineString lineString, GISDisplay display) {
Paint paint = new Paint();
paint.setColor(mColor);
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeCap(Paint.Cap.BUTT);
paint.setStrokeWidth(scaledWidth);
List<GeoPoint> points = lineString.getPoints();
// workaround for "DashPathEffect/drawLine not working properly when hardwareAccelerated="true""
// https://code.google.com/p/android/issues/detail?id=29944
// get all points to the main path
Path mainPath = new Path();
mainPath.incReserve(points.size());
mainPath.moveTo((float) points.get(0).getX(), (float) points.get(0).getY());
for (int i = 1; i < points.size(); ++i) {
mainPath.lineTo((float) points.get(i).getX(), (float) points.get(i).getY());
}
// draw along the main path
PathMeasure pm = new PathMeasure(mainPath, false);
float[] coordinates = new float[2];
float length = pm.getLength();
float dash = (float) (10 / display.getScale());
float gap = (float) (5 / display.getScale());
float distance = dash;
boolean isDash = true;
Path dashPath = new Path();
dashPath.incReserve((int) (2 * length / (dash + gap)));
dashPath.moveTo((float) points.get(0).getX(), (float) points.get(0).getY());
while (distance < length) {
// get a point from the main path
pm.getPosTan(distance, coordinates, null);
if (isDash) {
dashPath.lineTo(coordinates[0], coordinates[1]);
distance += gap;
} else {
dashPath.moveTo(coordinates[0], coordinates[1]);
distance += dash;
}
isDash = !isDash;
}
// add a rest from the main path
if (isDash) {
distance = distance - dash;
float rest = length - distance;
if (rest > (float) (1 / display.getScale())) {
distance = length - 1;
pm.getPosTan(distance, coordinates, null);
dashPath.lineTo(coordinates[0], coordinates[1]);
}
}
display.drawPath(dashPath, paint);
return mainPath;
}