@Override public void draw(Canvas canvas) { Rect bounds = getBounds(); paint.setColor(COLOR_LIGHT); int width = bounds.width() - STROKE_WIDTH; int height = bounds.height() - STROKE_WIDTH; canvas.drawPath(createLightPath(width, height), paint); paint.setColor(COLOR_DARK); canvas.drawPath(createDarkPath(width, height), paint); }
private void drawBrightnessIndicator(Canvas canvas) { // get a representation of the height of the indicator within the bar float brightnessHeight = mNewColor[2] * mWheel.getHeight(); // Log.d(TAG, String.format("Brightness height: %f", brightnessHeight)); // convert the height to an absolute y position based on the bar's position float absoluteY = mWheelPosition.y + mWheel.getHeight() - brightnessHeight; // get the y value "above" the x axis for the x coordinate calculation // note: because of symmetry, the sign doesn't matter so we'll use the positive float heightAboveXAxis = Math.abs(brightnessHeight - (float) mRadius); // Log.d(TAG, String.format("Height above X: %f", heightAboveXAxis)); float leftEdgeRadius = (float) (mRadius + SPACE_BETWEEN_WHEEL_AND_BAR); float rightEdgeRadius = leftEdgeRadius + ARC_WIDTH; // get the x coordinate relative to the center of the wheel float leftXInCircle = (float) Math.sqrt(leftEdgeRadius * leftEdgeRadius - heightAboveXAxis * heightAboveXAxis); float rightXInCircle = (float) Math.sqrt(rightEdgeRadius * rightEdgeRadius - heightAboveXAxis * heightAboveXAxis); // get the absolute x and y coordinates of the left edge of the bar at the bar height float leftX = mWheelCenter.x + leftXInCircle; float rightX = mWheelCenter.x + rightXInCircle; float indicatorHeight = BRIGHTNESS_INDICATOR_SIZE / 2.0f; float indicatorWidth = BRIGHTNESS_INDICATOR_SIZE; Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setStrokeWidth(1.0f); Path leftTrianglePath = new Path(); leftTrianglePath.moveTo(leftX, absoluteY - indicatorHeight); leftTrianglePath.lineTo(leftX + indicatorWidth, absoluteY); leftTrianglePath.lineTo(leftX, absoluteY + indicatorHeight); leftTrianglePath.close(); paint.setColor(Color.BLUE); paint.setStyle(Paint.Style.FILL); canvas.drawPath(leftTrianglePath, paint); paint.setColor(Color.WHITE); paint.setStyle(Paint.Style.STROKE); canvas.drawPath(leftTrianglePath, paint); Path rightTrianglePath = new Path(); rightTrianglePath.moveTo(rightX, absoluteY - indicatorHeight); rightTrianglePath.lineTo(rightX - indicatorWidth, absoluteY); rightTrianglePath.lineTo(rightX, absoluteY + indicatorHeight); rightTrianglePath.close(); paint.setColor(Color.BLUE); paint.setStyle(Paint.Style.FILL); canvas.drawPath(rightTrianglePath, paint); paint.setColor(Color.WHITE); paint.setStyle(Paint.Style.STROKE); canvas.drawPath(rightTrianglePath, paint); }
@Override protected void onDraw(Canvas canvas) { // draw the background and color wheel canvas.drawBitmap(mBackground, mBackgroundPosition.x, mBackgroundPosition.y, null); canvas.drawBitmap(mWheel, mWheelPosition.x, mWheelPosition.y, null); // setup paint for the gradient filling Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setStyle(Paint.Style.FILL); paint.setStrokeWidth(2.0f); // create a shader that will show the range of brightness settings float[] gradientStartColor = new float[3]; float[] gradientEndColor = new float[3]; System.arraycopy(mNewColor, 0, gradientStartColor, 0, mNewColor.length); System.arraycopy(mNewColor, 0, gradientEndColor, 0, mNewColor.length); gradientStartColor[2] = 1.0f; gradientEndColor[2] = 0.0f; Shader gradientShader = new LinearGradient( (float) (mWheelPosition.x + mRadius), mWheelPosition.y, mOuterArcRect.right, mWheelPosition.y + mWheel.getHeight(), Color.HSVToColor(gradientStartColor), Color.HSVToColor(gradientEndColor), Shader.TileMode.MIRROR); paint.setShader(gradientShader); canvas.drawPath(mArcPath, paint); drawHSCrosshairs(canvas); drawBrightnessIndicator(canvas); }
private void touch_up() { mPath.lineTo(mX, mY); // commit the path to our offscreen mCanvas.drawPath(mPath, mPaint); // kill this so we don't double draw mPath.reset(); }
// ============================================================================== public final int[] renderGlyph( char glyph, Paint paint, android.graphics.Matrix matrix, Rect bounds) { Path p = new Path(); paint.getTextPath(String.valueOf(glyph), 0, 1, 0.0f, 0.0f, p); RectF boundsF = new RectF(); p.computeBounds(boundsF, true); matrix.mapRect(boundsF); boundsF.roundOut(bounds); bounds.left--; bounds.right++; final int w = bounds.width(); final int h = bounds.height(); Bitmap bm = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(bm); matrix.postTranslate(-bounds.left, -bounds.top); c.setMatrix(matrix); c.drawPath(p, paint); final int sizeNeeded = w * h; if (cachedRenderArray.length < sizeNeeded) cachedRenderArray = new int[sizeNeeded]; bm.getPixels(cachedRenderArray, 0, w, 0, 0, w, h); bm.recycle(); return cachedRenderArray; }
public void onDraw(Canvas canvas) { // 검정색 배경으로 지운다. 빈 화면이면 지우기만 하고 리턴 canvas.drawColor(Color.BLACK); if (status == BLANK) { return; } // 도형 목록을 순회하면서 도형 정보대로 출력한다. int idx; for (idx = 0; idx < arShape.size(); idx++) { Paint Pnt = new Paint(); Pnt.setAntiAlias(true); Pnt.setColor(arShape.get(idx).color); Rect rt = arShape.get(idx).rt; switch (arShape.get(idx).what) { case Shape.RECT: canvas.drawRect(rt, Pnt); break; case Shape.CIRCLE: canvas.drawCircle( rt.left + rt.width() / 2, rt.top + rt.height() / 2, rt.width() / 2, Pnt); break; case Shape.TRIANGLE: Path path = new Path(); path.moveTo(rt.left + rt.width() / 2, rt.top); path.lineTo(rt.left, rt.bottom); path.lineTo(rt.right, rt.bottom); canvas.drawPath(path, Pnt); break; } } }
@Override protected void onDraw(Canvas canvas) { canvas.drawColor(Color.LTGRAY); canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); canvas.drawPath(mPath, mPaint); }
private void drawRightUp(Canvas canvas) { Path path = new Path(); path.moveTo(getWidth(), roundHeight); path.lineTo(getWidth(), 0); path.lineTo(getWidth() - roundWidth, 0); path.arcTo(new RectF(getWidth() - roundWidth * 2, 0, getWidth(), 0 + roundHeight * 2), -90, 90); path.close(); canvas.drawPath(path, paint); }
private void drawLiftDown(Canvas canvas) { Path path = new Path(); path.moveTo(0, getHeight() - roundHeight); path.lineTo(0, getHeight()); path.lineTo(roundWidth, getHeight()); path.arcTo(new RectF(0, getHeight() - roundHeight * 2, 0 + roundWidth * 2, getWidth()), 90, 90); path.close(); canvas.drawPath(path, paint); }
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); }
void myDraw() { float width, height; width = getMeasuredWidth(); height = getMeasuredHeight(); canvas = holder.lockCanvas(); canvas.drawColor(Color.GREEN); canvas.drawPath(path, paint); holder.unlockCanvasAndPost(canvas); }
@Override void doDraw(Canvas canvas, Paint paint) { if (!mPath.isEmpty()) { paint.setStyle(Paint.Style.FILL); int color = blendColors(mStartColor, mEndColor, mCurrentScale); paint.setColor(color); canvas.drawPath(mPath, paint); } }
@Override protected void onDraw(Canvas canvas) { canvas.drawColor( (props.containsKeyAndNotNull(TiC.PROPERTY_BACKGROUND_COLOR)) ? TiConvert.toColor(props, TiC.PROPERTY_BACKGROUND_COLOR) : TiConvert.toColor("transparent")); canvas.drawBitmap(tiBitmap, 0, 0, tiBitmapPaint); canvas.drawPath(tiPath, tiPaint); }
/** * 画X,Y轴和边框 * * @param canvas */ private void drawAxesLine(Canvas canvas) { XYpaint = new Paint(); XYpaint.setColor(axesLineColor); XYpaint.setAntiAlias(true); XYpaint.setStyle(Style.FILL_AND_STROKE); XYpaint.setStrokeWidth(chartFrameLineSize); // 左侧Y轴 canvas.drawLine( leftPadding + yTextWidth, topPadding + topTextHeight, leftPadding + yTextWidth, height - bottomPadding - xTextHeight, XYpaint); // 三角箭头 Path yTriangle = new Path(); yTriangle.moveTo(leftPadding + yTextWidth - 10, topPadding + topTextHeight); yTriangle.lineTo(leftPadding + yTextWidth, topPadding + topTextHeight - 20); yTriangle.lineTo(leftPadding + yTextWidth + 10, topPadding + topTextHeight); yTriangle.close(); canvas.drawPath(yTriangle, XYpaint); // 下方X轴 canvas.drawLine( leftPadding + yTextWidth, height - bottomPadding - xTextHeight, width - rightPadding, height - bottomPadding - xTextHeight, XYpaint); // 三角箭头 Path xTriangle = new Path(); xTriangle.moveTo(width - rightPadding, height - bottomPadding - xTextHeight + 10); xTriangle.lineTo(width - rightPadding + 15, height - bottomPadding - xTextHeight); xTriangle.lineTo(width - rightPadding, height - bottomPadding - xTextHeight - 10); xTriangle.close(); canvas.drawPath(xTriangle, XYpaint); // 上方封顶 // canvas.drawLine(leftPadding + xTextHeight, topPadding + topTextHeight, width - rightPadding, // topPadding + topTextHeight, XYpaint); // 右侧封边 // canvas.drawLine(width - rightPadding, topPadding + topTextHeight, width - rightPadding, // height - bottomPadding - xTextHeight, XYpaint); }
public void fillPolygon(int[] xps, int yps[], int c) { path = new Path(); int x; int y; for (int n = 0; n < c; n++) { x = xps[n]; y = yps[n]; if (n == 0) path.moveTo(x, y); else path.lineTo(x, y); } canvas.drawPath(path, paint); }
/** * Draw a curvy stem tail. This is only used for single chords, not chord pairs. * * @param ytop The y location (in pixels) where the top of the staff starts. * @param topstaff The note at the top of the staff. */ private void DrawCurvyStem(Canvas canvas, Paint paint, int ytop, WhiteNote topstaff) { Path bezierPath; paint.setStrokeWidth(2); int xstart = 0; if (side == LeftSide) xstart = SheetMusic.LineSpace / 4 + 1; else xstart = SheetMusic.LineSpace / 4 + SheetMusic.NoteWidth; if (direction == Up) { int ystem = ytop + topstaff.Dist(end) * SheetMusic.NoteHeight / 2; if (duration == NoteDuration.Eighth || duration == NoteDuration.DottedEighth || duration == NoteDuration.Triplet || duration == NoteDuration.Sixteenth || duration == NoteDuration.ThirtySecond) { bezierPath = new Path(); bezierPath.moveTo(xstart, ystem); bezierPath.cubicTo( xstart, ystem + 3 * SheetMusic.LineSpace / 2, xstart + SheetMusic.LineSpace * 2, ystem + SheetMusic.NoteHeight * 2, xstart + SheetMusic.LineSpace / 2, ystem + SheetMusic.NoteHeight * 3); canvas.drawPath(bezierPath, paint); } ystem += SheetMusic.NoteHeight; if (duration == NoteDuration.Sixteenth || duration == NoteDuration.ThirtySecond) { bezierPath = new Path(); bezierPath.moveTo(xstart, ystem); bezierPath.cubicTo( xstart, ystem + 3 * SheetMusic.LineSpace / 2, xstart + SheetMusic.LineSpace * 2, ystem + SheetMusic.NoteHeight * 2, xstart + SheetMusic.LineSpace / 2, ystem + SheetMusic.NoteHeight * 3); canvas.drawPath(bezierPath, paint); } ystem += SheetMusic.NoteHeight; if (duration == NoteDuration.ThirtySecond) { bezierPath = new Path(); bezierPath.moveTo(xstart, ystem); bezierPath.cubicTo( xstart, ystem + 3 * SheetMusic.LineSpace / 2, xstart + SheetMusic.LineSpace * 2, ystem + SheetMusic.NoteHeight * 2, xstart + SheetMusic.LineSpace / 2, ystem + SheetMusic.NoteHeight * 3); canvas.drawPath(bezierPath, paint); } } else if (direction == Down) { int ystem = ytop + topstaff.Dist(end) * SheetMusic.NoteHeight / 2 + SheetMusic.NoteHeight; if (duration == NoteDuration.Eighth || duration == NoteDuration.DottedEighth || duration == NoteDuration.Triplet || duration == NoteDuration.Sixteenth || duration == NoteDuration.ThirtySecond) { bezierPath = new Path(); bezierPath.moveTo(xstart, ystem); bezierPath.cubicTo( xstart, ystem - SheetMusic.LineSpace, xstart + SheetMusic.LineSpace * 2, ystem - SheetMusic.NoteHeight * 2, xstart + SheetMusic.LineSpace, ystem - SheetMusic.NoteHeight * 2 - SheetMusic.LineSpace / 2); canvas.drawPath(bezierPath, paint); } ystem -= SheetMusic.NoteHeight; if (duration == NoteDuration.Sixteenth || duration == NoteDuration.ThirtySecond) { bezierPath = new Path(); bezierPath.moveTo(xstart, ystem); bezierPath.cubicTo( xstart, ystem - SheetMusic.LineSpace, xstart + SheetMusic.LineSpace * 2, ystem - SheetMusic.NoteHeight * 2, xstart + SheetMusic.LineSpace, ystem - SheetMusic.NoteHeight * 2 - SheetMusic.LineSpace / 2); canvas.drawPath(bezierPath, paint); } ystem -= SheetMusic.NoteHeight; if (duration == NoteDuration.ThirtySecond) { bezierPath = new Path(); bezierPath.moveTo(xstart, ystem); bezierPath.cubicTo( xstart, ystem - SheetMusic.LineSpace, xstart + SheetMusic.LineSpace * 2, ystem - SheetMusic.NoteHeight * 2, xstart + SheetMusic.LineSpace, ystem - SheetMusic.NoteHeight * 2 - SheetMusic.LineSpace / 2); canvas.drawPath(bezierPath, paint); } } paint.setStrokeWidth(1); }
@Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { // Reset paint opacity paint.setAlpha(255); // Ignore everything but rectangles in bounds mode if (boundsMode) { if (localName.equals("rect")) { Float x = getFloatAttr("x", atts); if (x == null) { x = 0f; } Float y = getFloatAttr("y", atts); if (y == null) { y = 0f; } Float width = getFloatAttr("width", atts); Float height = getFloatAttr("height", atts); bounds = new RectF(x, y, x + width, y + height); } return; } if (localName.equals("svg")) { int width = (int) Math.ceil(getFloatAttr("width", atts)); int height = (int) Math.ceil(getFloatAttr("height", atts)); canvas = picture.beginRecording(width, height); } else if (localName.equals("defs")) { // Ignore } else if (localName.equals("linearGradient")) { gradient = doGradient(true, atts); } else if (localName.equals("radialGradient")) { gradient = doGradient(false, atts); } else if (localName.equals("stop")) { if (gradient != null) { float offset = getFloatAttr("offset", atts); String styles = getStringAttr("style", atts); StyleSet styleSet = new StyleSet(styles); String colorStyle = styleSet.getStyle("stop-color"); int color = Color.BLACK; if (colorStyle != null) { if (colorStyle.startsWith("#")) { color = Integer.parseInt(colorStyle.substring(1), 16); } else { color = Integer.parseInt(colorStyle, 16); } } String opacityStyle = styleSet.getStyle("stop-opacity"); if (opacityStyle != null) { float alpha = Float.parseFloat(opacityStyle); int alphaInt = Math.round(255 * alpha); color |= (alphaInt << 24); } else { color |= 0xFF000000; } gradient.positions.add(offset); gradient.colors.add(color); } } else if (localName.equals("g")) { // Check to see if this is the "bounds" layer if ("bounds".equalsIgnoreCase(getStringAttr("id", atts))) { boundsMode = true; } if (hidden) { hiddenLevel++; // Util.debug("Hidden up: " + hiddenLevel); } // Go in to hidden mode if display is "none" if ("none".equals(getStringAttr("display", atts))) { if (!hidden) { hidden = true; hiddenLevel = 1; // Util.debug("Hidden up: " + hiddenLevel); } } pushTransform(atts); } else if (!hidden && localName.equals("rect")) { Float x = getFloatAttr("x", atts); if (x == null) { x = 0f; } Float y = getFloatAttr("y", atts); if (y == null) { y = 0f; } Float width = getFloatAttr("width", atts); Float height = getFloatAttr("height", atts); Float rx = getFloatAttr("rx", atts); Float ry = getFloatAttr("ry", atts); if (rx == null) { if (ry == null) rx = ry = 0f; else rx = ry; } else { if (ry == null) ry = rx; } if (rx > width / 2) rx = width * 0.5f; if (ry > height / 2) ry = height * 0.5f; pushTransform(atts); Properties props = new Properties(atts); if (doFill(props, gradientMap)) { doLimits(x, y, width, height); if (rx > 0 && ry > 0) canvas.drawRoundRect(new RectF(x, y, x + width, y + height), rx, ry, paint); else canvas.drawRect(x, y, x + width, y + height, paint); } if (doStroke(props, gradientMap)) { if (rx > 0 && ry > 0) canvas.drawRoundRect(new RectF(x, y, x + width, y + height), rx, ry, paint); else canvas.drawRect(x, y, x + width, y + height, paint); } popTransform(); } else if (!hidden && localName.equals("line")) { Float x1 = getFloatAttr("x1", atts); Float x2 = getFloatAttr("x2", atts); Float y1 = getFloatAttr("y1", atts); Float y2 = getFloatAttr("y2", atts); Properties props = new Properties(atts); if (doStroke(props, gradientMap)) { pushTransform(atts); doLimits(x1, y1); doLimits(x2, y2); canvas.drawLine(x1, y1, x2, y2, paint); popTransform(); } } else if (!hidden && localName.equals("circle")) { Float centerX = getFloatAttr("cx", atts); Float centerY = getFloatAttr("cy", atts); Float radius = getFloatAttr("r", atts); if (centerX != null && centerY != null && radius != null) { pushTransform(atts); Properties props = new Properties(atts); if (doFill(props, gradientMap)) { doLimits(centerX - radius, centerY - radius); doLimits(centerX + radius, centerY + radius); canvas.drawCircle(centerX, centerY, radius, paint); } if (doStroke(props, gradientMap)) { canvas.drawCircle(centerX, centerY, radius, paint); } popTransform(); } } else if (!hidden && localName.equals("ellipse")) { Float centerX = getFloatAttr("cx", atts); Float centerY = getFloatAttr("cy", atts); Float radiusX = getFloatAttr("rx", atts); Float radiusY = getFloatAttr("ry", atts); if (centerX != null && centerY != null && radiusX != null && radiusY != null) { pushTransform(atts); Properties props = new Properties(atts); rect.set(centerX - radiusX, centerY - radiusY, centerX + radiusX, centerY + radiusY); if (doFill(props, gradientMap)) { doLimits(centerX - radiusX, centerY - radiusY); doLimits(centerX + radiusX, centerY + radiusY); canvas.drawOval(rect, paint); } if (doStroke(props, gradientMap)) { canvas.drawOval(rect, paint); } popTransform(); } } else if (!hidden && (localName.equals("polygon") || localName.equals("polyline"))) { NumberParse numbers = getNumberParseAttr("points", atts); if (numbers != null) { Path p = new Path(); ArrayList<Float> points = numbers.numbers; if (points.size() > 1) { pushTransform(atts); Properties props = new Properties(atts); p.moveTo(points.get(0), points.get(1)); for (int i = 2; i < points.size(); i += 2) { float x = points.get(i); float y = points.get(i + 1); p.lineTo(x, y); } // Don't close a polyline if (localName.equals("polygon")) { p.close(); } if (doFill(props, gradientMap)) { doLimits(p); canvas.drawPath(p, paint); } if (doStroke(props, gradientMap)) { canvas.drawPath(p, paint); } popTransform(); } } } else if (!hidden && localName.equals("path")) { Path p = doPath(getStringAttr("d", atts)); pushTransform(atts); Properties props = new Properties(atts); if (doFill(props, gradientMap)) { doLimits(p); canvas.drawPath(p, paint); } if (doStroke(props, gradientMap)) { canvas.drawPath(p, paint); } popTransform(); } else if (!hidden) { // Log.d(TAG, "UNRECOGNIZED SVG COMMAND: " + localName); } }
/** 绘画 */ @Override public void onDraw(Canvas canvas) { super.onDraw(canvas); // Log.v(TAG, "onDraw()"); vWidth = getWidth(); vHeight = getHeight(); // Log.v(TAG, vWidth + "--" + vHeight); // 中心 vLenght = vWidth / 2; // 弧度 double randian30 = 30 * Math.PI / 180; // Math.PI 圆周长和直径比值 a = (float) (vLenght * Math.sin(randian30)); b = (float) (vLenght * Math.cos(randian30)); c = (vHeight - 2 * b) / 2; // 画笔初始化 if (paint == null) { paint = new Paint(); // 去锯齿 paint.setAntiAlias(true); paint.setStyle(Style.FILL); paint.setColor(backColor); paint.setAlpha(100); } else { paint.setStyle(Style.FILL); paint.setColor(backColor); paint.setAlpha(100); } if (paint1 == null) { paint1 = new Paint(); // 去锯齿 paint1.setAntiAlias(true); // 重设画笔颜色 paint1.setColor(textColor); // 根据视图大小自动控制字体大小 if (textSize == -1) { if (src == null) { textSize = vWidth >= vHeight ? vHeight - 120 : vWidth - 120; if (textSize < 5) { textSize = 20; } } else { textSize = 24; } } paint1.setTextSize(textSize); // 画笔水平居中 paint1.setTextAlign(Align.CENTER); } // 画六边形 Path path = new Path(); path.moveTo(vWidth, vHeight / 2); path.lineTo(vWidth - a, vHeight - c); path.lineTo(vWidth - a - vLenght, vHeight - c); path.lineTo(0, vHeight / 2); path.lineTo(a, c); path.lineTo(vWidth - a, c); path.close(); // 画图形 canvas.drawPath(path, paint); // 画图片 if (src != null) { // paint.setAlpha(255); // 从Drawable中获取Bitmap BitmapDrawable bitmapD = (BitmapDrawable) src; Bitmap bitmap = bitmapD.getBitmap(); // 画背景图片,矩阵 // Matrix matrix = new Matrix(); // 转换矩阵,定位xy // matrix.postTranslate(vWidth / 2 - bitmap.getWidth() / 2, vHeight // / 2 - bitmap.getHeight() / 2); // 生成正六边形 mDrawable = new ShapeDrawable(new PathShape(path, vWidth, vHeight)); Shader aShader = new BitmapShader( zoomBitmap(bitmap, vWidth, vHeight), Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); mDrawable.getPaint().setShader(aShader); // 填充位图 mDrawable.setBounds(0, 0, vWidth, vHeight); // 设置边界尺寸 mDrawable.draw(canvas); // 绘制图片 // canvas.drawBitmap(bitmap, matrix, paint); } if (text != null) { // 计算文字高度,处理垂直居中 FontMetrics fontMetrics = paint1.getFontMetrics(); // 计算文字高度 float fontHeight = fontMetrics.bottom - fontMetrics.top; // 画字体 if (src != null) { // 如果有图片文字在底部 // Log.v(TAG, "src not null!"); canvas.drawText(text, vWidth / 2, 2 * b + c - 3, paint1); } else { // 没有图片时文字居于视图中央 float textBaseY = vHeight - (vHeight - fontHeight) / 2 - fontMetrics.bottom; canvas.drawText(text, vWidth / 2, textBaseY, paint1); } } // 六边形顶点位置 if (list == null) { list = new ArrayList<PointF>(); } else { list.clear(); } PointF pf = new PointF(); pf.set(vWidth, vHeight / 2); list.add(pf); PointF pf1 = new PointF(); pf1.set(vWidth - a, vHeight - c); list.add(pf1); PointF pf2 = new PointF(); pf2.set(vWidth - a - vLenght, vHeight - c); list.add(pf2); PointF pf3 = new PointF(); pf3.set(0, vHeight / 2); list.add(pf3); PointF pf4 = new PointF(); pf4.set(a, c); list.add(pf4); PointF pf5 = new PointF(); pf5.set(vWidth - a, c); list.add(pf5); lasso = LassoUtils.getInstance(); lasso.setLassoList(list); if (pf != null) { pf = null; pf1 = null; pf2 = null; pf3 = null; pf4 = null; pf5 = null; } }
/** * 画折线图,网格竖线,X坐标值 * * @param canvas */ private void drawChartLine(Canvas canvas) { Paint paintChart = new Paint(); paintChart.setColor(chartLineColor); paintChart.setAntiAlias(true); paintChart.setStyle(Style.STROKE); paintChart.setStrokeWidth(chartLineSize); Paint paintGrid = new Paint(); paintGrid.setColor(gridLineColor); paintGrid.setAntiAlias(true); paintGrid.setStyle(Style.STROKE); paintGrid.setStrokeWidth(gridLineSize); Paint paintTopText = new Paint(); paintTopText.setColor(axesLineColor); paintTopText.setAntiAlias(true); paintTopText.setSubpixelText(true); paintTopText.setTypeface(Typeface.MONOSPACE); paintTopText.setTextSize(topTextSize); paintTopText.setTextAlign(Align.CENTER); Paint paintBottomText = new Paint(); paintBottomText.setColor(axesLineColor); paintBottomText.setAntiAlias(true); paintBottomText.setSubpixelText(true); paintBottomText.setTypeface(Typeface.MONOSPACE); paintBottomText.setTextSize(bottomTextSize); paintBottomText.setTextAlign(Align.CENTER); Paint paintPoint = new Paint(); paintPoint.setColor(pointColor); paintPoint.setAntiAlias(true); paintPoint.setStyle(Style.FILL); pressedPaint = new Paint(); pressedPaint.setColor(pressedColor); pressedPaint.setAntiAlias(true); pressedPaint.setStyle(Style.FILL); Paint paintShape = new Paint(); paintShape.setStyle(Style.FILL); paintShape.setColor(shapeColor); paintShape.setAlpha(shapeAlpha); if (axesData.size() > 0) { for (int i = 0; i < axesData.size(); i++) { if (i < axesData.size() - 1) { // 画折线 canvas.drawLine( axesData.get(i).X, axesData.get(i).Y, axesData.get(i + 1).X, axesData.get(i + 1).Y, paintChart); if (isShapeShow) { // 画阴影 Path path = new Path(); path.moveTo(axesData.get(i).X, height - bottomPadding - xTextHeight); path.lineTo(axesData.get(i).X, axesData.get(i).Y + chartLineSize / 2); path.lineTo(axesData.get(i + 1).X, axesData.get(i + 1).Y + chartLineSize / 2); path.lineTo(axesData.get(i + 1).X, height - bottomPadding - xTextHeight); canvas.drawPath(path, paintShape); } } // 画网格竖线 // canvas.drawLine(axesData.get(i).X, height - bottomPadding - xTextHeight, // axesData.get(i).X, topPadding + topTextHeight, paintGrid); // 写X轴坐标的刻度值 if (!TextUtils.isEmpty(axesData.get(i).getxText())) { setTextSizeForWidth( paintBottomText, spaceXLength - 10, axesData.get(i).getxText()); // 10为相邻日期文字间隔 canvas.drawText( axesData.get(i).getxText(), axesData.get(i).X, height - bottomPadding - xTextHeight / 2, paintBottomText); } // 写顶部的刻度值 if (!TextUtils.isEmpty(axesData.get(i).getTopText())) { // 取消了顶部隔年显示的数据 // canvas.drawText(axesData.get(i).getTopText(), axesData.get(i).X, topPadding, // paintTopText); } // 画数据点 if (pointBitmap == null) { canvas.drawCircle(axesData.get(i).X, axesData.get(i).Y, pointSize + 1, paintChart); canvas.drawCircle(axesData.get(i).X, axesData.get(i).Y, pointSize, paintPoint); } else { Matrix matrix = new Matrix(); canvas.drawBitmap(pointBitmap, matrix, paintPoint); } } // 画最后一个数据的网格竖线 // canvas.drawLine(axesData.get(axesData.size() - 1).X, height - bottomPadding - xTextHeight, // axesData.get(axesData.size() - 1).X, // topPadding + topTextHeight, paintGrid); // 写X轴坐标的最后一个值的刻度值 /* * canvas.drawText(axesData.get(axesData.size() - 1).X + "", * axesData.get(axesData.size() - 1).X, height - bottomPadding - * xTextHeight / 2, paintBottomText); */ // 写顶部的最后一个刻度值 // canvas.drawText("2014", axesData.get(axesData.size() - 1).X, // topPadding, paintTopText); // 画数最后一个据点 if (pointBitmap == null) { // canvas.drawCircle(axesData.get(axesData.size() - 1).X, // axesData.get(axesData.size() - 1).Y, pointSize + 1, // paintChart); // canvas.drawCircle(axesData.get(axesData.size() - 1).X, // axesData.get(axesData.size() - 1).Y, pointSize, paintPoint); } else { Matrix matrix = new Matrix(); canvas.drawBitmap(pointBitmap, matrix, paintPoint); } } if (currentPressedPoint != null) { // canvas.drawCircle(currentPressedPoint.X, currentPressedPoint.Y, pointSize, pressedPaint); } }
private void touch_up() { tiPath.lineTo(tiX, tiY); tiCanvas.drawPath(tiPath, tiPaint); tiPath.reset(); }
private void stroke(Seria s, Canvas canvas) { mPlotPaint.setStyle(Paint.Style.STROKE); // draw line if (s.mWidth > 0) { // create the path mPath.reset(); mPath.moveTo(calcX(s.x[0]), calcY(s.y[0])); for (int i = 1; i < s.sz(); i++) { mPath.lineTo(calcX(s.x[i]), calcY(s.y[i])); } // draw the path mPlotPaint.setColor(s.mColor); mPlotPaint.setStrokeWidth(s.mWidth); mPlotPaint.setPathEffect(s.mEffect); canvas.drawPath(mPath, mPlotPaint); } // draw images seria if (s.bms != null) { for (int i = 0; i < s.sz(); i++) { Bitmap bm; if (s.bms.length > 1) { bm = s.bms[i]; } else { bm = s.bms[0]; } float left = calcX(s.x[i]); float top = calcY(s.y[i]); if (s.hAlign == HALIGN.CENTER) { left -= bm.getWidth() / 2; } else if (s.hAlign == HALIGN.RIGHT) { left -= bm.getWidth(); } if (s.vAlign == VALIGN.CENTER) { top -= bm.getHeight() / 2; } else if (s.vAlign == VALIGN.BOTTOM) { top -= bm.getHeight(); } canvas.drawBitmap(s.bms[i], left, top, mPlotPaint); } } if (s.texts != null) { Align align = Align.CENTER; switch (s.hAlign) { case LEFT: align = Align.RIGHT; case RIGHT: align = Align.LEFT; } mPlotPaint.setTextAlign(align); mPlotPaint.setStrokeWidth(0); mPlotPaint.setColor(s.mColor); for (int i = 0; i < s.sz(); i++) { float x = calcX(s.x[i]); float y = calcY(s.y[i]); switch (s.vAlign) { case TOP: y -= mPlotPaint.getTextSize(); case CENTER: y -= 0.5 * mPlotPaint.getTextSize(); } if (s.deg != 0) { canvas.save(); canvas.rotate(s.deg, x, y); } canvas.drawText(s.texts[i], x, y, mPlotPaint); if (s.deg != 0) { canvas.restore(); } } } }
public void onDraw(Canvas canvas) { canvas.drawColor(Color.TRANSPARENT); paint.reset(); paint.setAntiAlias(true); float midX, midY, radius, innerRadius; path.reset(); float currentAngle = 270; float currentSweep; int totalValue = 0; float padding = 2; midX = getWidth() / 2; midY = getHeight() / 2; if (midX < midY) { radius = midX; } else { radius = midY; } radius -= padding; innerRadius = radius - thickness; for (PieSlice slice : slices) { totalValue += slice.getValue(); } int count = 0; for (PieSlice slice : slices) { Path p = new Path(); paint.setColor(slice.getColor()); currentSweep = (slice.getValue() / totalValue) * (360); p.arcTo( new RectF(midX - radius, midY - radius, midX + radius, midY + radius), currentAngle + padding, currentSweep - padding); p.arcTo( new RectF(midX - innerRadius, midY - innerRadius, midX + innerRadius, midY + innerRadius), (currentAngle + padding) + (currentSweep - padding), -(currentSweep - padding)); p.close(); slice.setPath(p); slice.setRegion( new Region( (int) (midX - radius), (int) (midY - radius), (int) (midX + radius), (int) (midY + radius))); canvas.drawPath(p, paint); if (indexSelected == count && listener != null) { path.reset(); paint.setColor(slice.getColor()); paint.setColor(Color.parseColor("#33B5E5")); paint.setAlpha(100); if (slices.size() > 1) { path.arcTo( new RectF( midX - radius - (padding * 2), midY - radius - (padding * 2), midX + radius + (padding * 2), midY + radius + (padding * 2)), currentAngle, currentSweep + padding); path.arcTo( new RectF( midX - innerRadius + (padding * 2), midY - innerRadius + (padding * 2), midX + innerRadius - (padding * 2), midY + innerRadius - (padding * 2)), currentAngle + currentSweep + padding, -(currentSweep + padding)); path.close(); } else { path.addCircle(midX, midY, radius + padding, Direction.CW); } canvas.drawPath(path, paint); paint.setAlpha(255); } currentAngle = currentAngle + currentSweep; count++; } }
/** * 自定义的方法,简单绘制一些基本图形 * * @param mCanvas 把图形画在mCanvas上 */ public void canvasMethod(Canvas mCanvas) { // 创建对应坐标的矩形区域 RectF mArc = new RectF(mX, mY - 70, mX + 50, mY - 20); // 画填充弧,在矩形区域内,从弧的最右边开始,画270度,然后再通过连接圆心来填充 mCanvas.drawArc(mArc, 0, 270, true, mPaint); // 获得icon的Bitmap对象 Bitmap mBitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); // 画图片 mCanvas.drawBitmap(mBitmap, mX, mY, mPaint); // 画圆,(x轴,y轴,半径,画笔) mCanvas.drawCircle(mX + 10, mY + 60, 10, mPaint); // 画一条线,(起点横坐标,起点纵坐标,终点横坐标,终点纵坐标,画笔) mCanvas.drawLine(mX, mY + 75, mX + 20, mY + 75, mPaint); // 画多条线,(坐标数组,画笔)坐标数组里每四个值构成一条线 mCanvas.drawLines( new float[] {mX + 50, mY + 45, mX + 50, mY + 75, mX + 60, mY + 45, mX + 60, mY + 75}, mPaint); // 创建对应矩形区域 RectF mOval = new RectF(mX, mY + 80, mX + 60, mY + 110); // 画椭圆 mCanvas.drawOval(mOval, mPaint); /* * Paint qPaint = new Paint(); qPaint.setColor(Color.RED); * mCanvas.drawPaint(qPaint); */ // 重置Path里的所有路径 mPath.reset(); // 设置Path的起点 mPath.moveTo(mX, mY + 120); // 第二个点 mPath.lineTo(screenW - 10, mY + 120); // 第三个点 mPath.lineTo(screenW - 10, mY + 150); // 画出路径,这里画的是三角形 mCanvas.drawPath(mPath, mPaint); // 重置Path里的所有路径 qPath.reset(); // 设置Path的起点 qPath.moveTo(qStartX, qStartY); // 设置贝塞尔曲线的控制点坐标和终点坐标 qPath.quadTo(qControlX, qCOntrolY, qEndX, qEndY); // 画出贝塞尔曲线 mCanvas.drawPath(qPath, qPaint); // 画点 mCanvas.drawPoint(mX, mY + 155, qPaint); // 画多个点,坐标数组每两个值代表一个点的坐标 mCanvas.drawPoints(new float[] {mX, mY + 160, mX + 5, mY + 160, mX + 5, mY + 160}, qPaint); // 画矩形 mCanvas.drawRect(mX, mY + 170, mX + 100, mY + 220, mPaint); // 设置矩形区域 RectF mRect = new RectF(mX, mY + 230, mX + 100, mY + 260); // 画圆角矩形,这个方法的第二第三个参数在后面有图讲解 mCanvas.drawRoundRect(mRect, 10, 10, mPaint); // 画文本 mCanvas.drawText("drawText", mX, mY + 290, mPaint); // 画文本,数组里每两个值代表文本的一个字符的坐标,数组的坐标可以比字符串里的字符多,但不可以少 mCanvas.drawPosText( "哈哈你好", new float[] {mX, mY + 310, mX + 20, mY + 310, mX + 40, mY + 310, mX + 60, mY + 310}, mPaint); // 重置Path tPath.reset(); // 添加一个圆形路径,坐标,半径,方向(顺时针还是逆时针) tPath.addCircle(mX + 10, mY + 340, 10, Path.Direction.CW); // 画出路径 mCanvas.drawPath(tPath, qPaint); // 把文本画在路径上,但不会画出路径 mCanvas.drawTextOnPath("draw", tPath, 30, 0, mPaint); }
private void drawHSCrosshairs(Canvas canvas) { float crosshairsRadius = CROSSHAIRS_SIZE / 2.0f; float[] HSCrosshairsCenter = findCrosshairsCenter(); // Log.d(TAG, String.format("Reference point: (%f, %f)", HSCrosshairsCenter[0], // HSCrosshairsCenter[1])); // find the actual coordinates of the center of the crosshairs wrt the whole screen float absoluteCenterX = (float) mWheelCenter.x + HSCrosshairsCenter[0]; // note: the (-) is intentional due to the inversion of the y coordinate system (wrt cartesian) float absoluteCenterY = (float) mWheelCenter.y - HSCrosshairsCenter[1]; // make convenience variables for size float topBottomWidth = 0.35f * CROSSHAIRS_SIZE; float topBottomHeight = 0.3f * CROSSHAIRS_SIZE; float leftRightWidth = 0.3f * CROSSHAIRS_SIZE; float leftRightHeight = 0.35f * CROSSHAIRS_SIZE; // make convenience variables for bounds float left = absoluteCenterX - crosshairsRadius; float right = absoluteCenterX + crosshairsRadius; float top = absoluteCenterY - crosshairsRadius; float bottom = absoluteCenterY + crosshairsRadius; Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setStrokeWidth(1.0f); // draw the top triangle Path topTrianglePath = new Path(); topTrianglePath.moveTo(absoluteCenterX - topBottomWidth, top); topTrianglePath.lineTo(absoluteCenterX + topBottomWidth, top); topTrianglePath.lineTo(absoluteCenterX, top + topBottomHeight); topTrianglePath.close(); paint.setColor(Color.BLUE); paint.setStyle(Paint.Style.FILL); canvas.drawPath(topTrianglePath, paint); paint.setColor(Color.WHITE); paint.setStyle(Paint.Style.STROKE); canvas.drawPath(topTrianglePath, paint); // draw the bottom triangle Path bottomTrianglePath = new Path(); bottomTrianglePath.moveTo(absoluteCenterX + topBottomWidth, bottom); bottomTrianglePath.lineTo(absoluteCenterX - topBottomWidth, bottom); bottomTrianglePath.lineTo(absoluteCenterX, bottom - topBottomHeight); bottomTrianglePath.close(); paint.setColor(Color.BLUE); paint.setStyle(Paint.Style.FILL); canvas.drawPath(bottomTrianglePath, paint); paint.setColor(Color.WHITE); paint.setStyle(Paint.Style.STROKE); canvas.drawPath(bottomTrianglePath, paint); // draw the left triangle Path leftTrianglePath = new Path(); leftTrianglePath.moveTo(left, absoluteCenterY + leftRightHeight); leftTrianglePath.lineTo(left, absoluteCenterY - leftRightHeight); leftTrianglePath.lineTo(left + leftRightWidth, absoluteCenterY); leftTrianglePath.close(); paint.setColor(Color.BLUE); paint.setStyle(Paint.Style.FILL); canvas.drawPath(leftTrianglePath, paint); paint.setColor(Color.WHITE); paint.setStyle(Paint.Style.STROKE); canvas.drawPath(leftTrianglePath, paint); // draw the right triangle Path rightTrianglePath = new Path(); rightTrianglePath.moveTo(right, absoluteCenterY - leftRightHeight); rightTrianglePath.lineTo(right, absoluteCenterY + leftRightHeight); rightTrianglePath.lineTo(right - leftRightWidth, absoluteCenterY); rightTrianglePath.close(); paint.setColor(Color.BLUE); paint.setStyle(Paint.Style.FILL); canvas.drawPath(rightTrianglePath, paint); paint.setColor(Color.WHITE); paint.setStyle(Paint.Style.STROKE); canvas.drawPath(rightTrianglePath, paint); }
protected void draw(Canvas canvas) { if (mHidden) { return; } Path path = new Path(); if (!hasFocus()) { mOutlinePaint.setColor(0xFF000000); canvas.drawRect(mDrawRect, mOutlinePaint); } else { Rect viewDrawingRect = new Rect(); mContext.getDrawingRect(viewDrawingRect); if (mCircle) { canvas.save(); float width = mDrawRect.width(); float height = mDrawRect.height(); path.addCircle( mDrawRect.left + (width / 2), mDrawRect.top + (height / 2), width / 2, Path.Direction.CW); mOutlinePaint.setColor(0xFFEF04D6); mOutlinePaint.setColor(0x0a83fe); canvas.clipPath(path, Region.Op.DIFFERENCE); canvas.drawRect(viewDrawingRect, hasFocus() ? mFocusPaint : mNoFocusPaint); canvas.restore(); } else { Rect topRect = new Rect( viewDrawingRect.left, viewDrawingRect.top, viewDrawingRect.right, mDrawRect.top); if (topRect.width() > 0 && topRect.height() > 0) { canvas.drawRect(topRect, hasFocus() ? mFocusPaint : mNoFocusPaint); } Rect bottomRect = new Rect( viewDrawingRect.left, mDrawRect.bottom, viewDrawingRect.right, viewDrawingRect.bottom); if (bottomRect.width() > 0 && bottomRect.height() > 0) { canvas.drawRect(bottomRect, hasFocus() ? mFocusPaint : mNoFocusPaint); } Rect leftRect = new Rect(viewDrawingRect.left, topRect.bottom, mDrawRect.left, bottomRect.top); if (leftRect.width() > 0 && leftRect.height() > 0) { canvas.drawRect(leftRect, hasFocus() ? mFocusPaint : mNoFocusPaint); } Rect rightRect = new Rect(mDrawRect.right, topRect.bottom, viewDrawingRect.right, bottomRect.top); if (rightRect.width() > 0 && rightRect.height() > 0) { canvas.drawRect(rightRect, hasFocus() ? mFocusPaint : mNoFocusPaint); } path.addRect(new RectF(mDrawRect), Path.Direction.CW); mOutlinePaint.setColor(Color.parseColor("#0a83fe")); } canvas.drawPath(path, mOutlinePaint); if (mMode == ModifyMode.Grow) { if (mCircle) { int width = mResizeDrawableDiagonal.getIntrinsicWidth(); int height = mResizeDrawableDiagonal.getIntrinsicHeight(); int d = (int) Math.round(Math.cos(/* 45deg */ Math.PI / 4D) * (mDrawRect.width() / 2D)); int x = mDrawRect.left + (mDrawRect.width() / 2) + d - width / 2; int y = mDrawRect.top + (mDrawRect.height() / 2) - d - height / 2; mResizeDrawableDiagonal.setBounds( x, y, x + mResizeDrawableDiagonal.getIntrinsicWidth(), y + mResizeDrawableDiagonal.getIntrinsicHeight()); mResizeDrawableDiagonal.draw(canvas); } else { int left = mDrawRect.left + 1; int right = mDrawRect.right + 1; int top = mDrawRect.top + 4; int bottom = mDrawRect.bottom + 3; int widthWidth = mResizeDrawableWidth.getIntrinsicWidth() / 2; int widthHeight = mResizeDrawableWidth.getIntrinsicHeight() / 2; int heightHeight = mResizeDrawableHeight.getIntrinsicHeight() / 2; int heightWidth = mResizeDrawableHeight.getIntrinsicWidth() / 2; int xMiddle = mDrawRect.left + ((mDrawRect.right - mDrawRect.left) / 2); int yMiddle = mDrawRect.top + ((mDrawRect.bottom - mDrawRect.top) / 2); mResizeDrawableWidth.setBounds( left - widthWidth, yMiddle - widthHeight, left + widthWidth, yMiddle + widthHeight); mResizeDrawableWidth.draw(canvas); mResizeDrawableWidth.setBounds( right - widthWidth, yMiddle - widthHeight, right + widthWidth, yMiddle + widthHeight); mResizeDrawableWidth.draw(canvas); mResizeDrawableHeight.setBounds( xMiddle - heightWidth, top - heightHeight, xMiddle + heightWidth, top + heightHeight); mResizeDrawableHeight.draw(canvas); mResizeDrawableHeight.setBounds( xMiddle - heightWidth, bottom - heightHeight, xMiddle + heightWidth, bottom + heightHeight); mResizeDrawableHeight.draw(canvas); } } } }
@Override public void onDraw(Canvas canvas) { canvas.drawPath(path, paint); }
@Override protected void onDraw(Canvas canvas) { float ringWidth = textHeight + 4; int height = getMeasuredHeight(); int width = getMeasuredWidth(); int px = width / 2; int py = height / 2; Point center = new Point(px, py); int radius = Math.min(px, py) - 2; RectF boundingBox = new RectF(center.x - radius, center.y - radius, center.x + radius, center.y + radius); RectF innerBoundingBox = new RectF( center.x - radius + ringWidth, center.y - radius + ringWidth, center.x + radius - ringWidth, center.y + radius - ringWidth); float innerRadius = innerBoundingBox.height() / 2; RadialGradient borderGradient = new RadialGradient( px, py, radius, borderGradientColors, borderGradientPositions, TileMode.CLAMP); Paint pgb = new Paint(); pgb.setShader(borderGradient); Path outerRingPath = new Path(); outerRingPath.addOval(boundingBox, Direction.CW); canvas.drawPath(outerRingPath, pgb); LinearGradient skyShader = new LinearGradient( center.x, innerBoundingBox.top, center.x, innerBoundingBox.bottom, skyHorizonColorFrom, skyHorizonColorTo, TileMode.CLAMP); Paint skyPaint = new Paint(); skyPaint.setShader(skyShader); LinearGradient groundShader = new LinearGradient( center.x, innerBoundingBox.top, center.x, innerBoundingBox.bottom, groundHorizonColorFrom, groundHorizonColorTo, TileMode.CLAMP); Paint groundPaint = new Paint(); groundPaint.setShader(groundShader); float tiltDegree = pitch; while (tiltDegree > 90 || tiltDegree < -90) { if (tiltDegree > 90) tiltDegree = -90 + (tiltDegree - 90); if (tiltDegree < -90) tiltDegree = 90 - (tiltDegree + 90); } float rollDegree = roll; while (rollDegree > 180 || rollDegree < -180) { if (rollDegree > 180) rollDegree = -180 + (rollDegree - 180); if (rollDegree < -180) rollDegree = 180 - (rollDegree + 180); } Path skyPath = new Path(); skyPath.addArc(innerBoundingBox, -rollDegree, (180 + (2 * rollDegree))); canvas.rotate(-tiltDegree, px, py); canvas.drawOval(innerBoundingBox, groundPaint); canvas.drawPath(skyPath, skyPaint); canvas.drawPath(skyPath, markerPaint); int markWidth = radius / 3; int startX = center.x - markWidth; int endX = center.x + markWidth; Log.d("PAARV ", "Roll " + String.valueOf(rollDegree)); Log.d("PAARV ", "Pitch " + String.valueOf(tiltDegree)); double h = innerRadius * Math.cos(Math.toRadians(90 - tiltDegree)); double justTiltX = center.x - h; float pxPerDegree = (innerBoundingBox.height() / 2) / 45f; for (int i = 90; i >= -90; i -= 10) { double ypos = justTiltX + i * pxPerDegree; if ((ypos < (innerBoundingBox.top + textHeight)) || (ypos > innerBoundingBox.bottom - textHeight)) continue; canvas.drawLine(startX, (float) ypos, endX, (float) ypos, markerPaint); int displayPos = (int) (tiltDegree - i); String displayString = String.valueOf(displayPos); float stringSizeWidth = textPaint.measureText(displayString); canvas.drawText( displayString, (int) (center.x - stringSizeWidth / 2), (int) (ypos) + 1, textPaint); } markerPaint.setStrokeWidth(2); canvas.drawLine( center.x - radius / 2, (float) justTiltX, center.x + radius / 2, (float) justTiltX, markerPaint); markerPaint.setStrokeWidth(1); Path rollArrow = new Path(); rollArrow.moveTo(center.x - 3, (int) innerBoundingBox.top + 14); rollArrow.lineTo(center.x, (int) innerBoundingBox.top + 10); rollArrow.moveTo(center.x + 3, innerBoundingBox.top + 14); rollArrow.lineTo(center.x, innerBoundingBox.top + 10); canvas.drawPath(rollArrow, markerPaint); String rollText = String.valueOf(rollDegree); double rollTextWidth = textPaint.measureText(rollText); canvas.drawText( rollText, (float) (center.x - rollTextWidth / 2), innerBoundingBox.top + textHeight + 2, textPaint); canvas.restore(); canvas.save(); canvas.rotate(180, center.x, center.y); for (int i = -180; i < 180; i += 10) { if (i % 30 == 0) { String rollString = String.valueOf(i * -1); float rollStringWidth = textPaint.measureText(rollString); PointF rollStringCenter = new PointF(center.x - rollStringWidth / 2, innerBoundingBox.top + 1 + textHeight); canvas.drawText(rollString, rollStringCenter.x, rollStringCenter.y, textPaint); } else { canvas.drawLine( center.x, (int) innerBoundingBox.top, center.x, (int) innerBoundingBox.top + 5, markerPaint); } canvas.rotate(10, center.x, center.y); } canvas.restore(); canvas.save(); canvas.rotate(-1 * (bearing), px, py); double increment = 22.5; for (double i = 0; i < 360; i += increment) { CompassDirection cd = CompassDirection.values()[(int) (i / 22.5)]; String headString = cd.toString(); float headStringWidth = textPaint.measureText(headString); PointF headStringCenter = new PointF(center.x - headStringWidth / 2, boundingBox.top + 1 + textHeight); if (i % increment == 0) canvas.drawText(headString, headStringCenter.x, headStringCenter.y, textPaint); else canvas.drawLine( center.x, (int) boundingBox.top, center.x, (int) boundingBox.top + 3, markerPaint); canvas.rotate((int) increment, center.x, center.y); } canvas.restore(); RadialGradient glassShader = new RadialGradient( px, py, (int) innerRadius, glassGradientColors, glassGradientPositions, TileMode.CLAMP); Paint glassPaint = new Paint(); glassPaint.setShader(glassShader); canvas.drawOval(innerBoundingBox, glassPaint); canvas.drawOval(boundingBox, circlePaint); circlePaint.setStrokeWidth(2); canvas.drawOval(innerBoundingBox, circlePaint); canvas.restore(); }
@Override protected void onDraw(Canvas canvas) { canvas.drawPath(path, paint); }
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.TRANSPARENT); int startCircleX = 0, startCircleY = 0; if (isTouched) { // 触摸状态 startCircleX = startPoint.x + curRadius; startCircleY = startPoint.y - curRadius; // 绘制原来的圆形(触摸移动的时候半径会不断变化) canvas.drawCircle(startCircleX, startCircleY, curRadius, paint); // 绘制手指跟踪的圆形 int endCircleX = endPoint.x; int endCircleY = endPoint.y; canvas.drawCircle(endCircleX, endCircleY, originRadius, paint); if (!isArrivedMaxMoved) { // 没有达到拉伸最大值 path.reset(); double sin = triangle.deltaY / triangle.hypotenuse; double cos = triangle.deltaX / triangle.hypotenuse; // A点 path.moveTo( (float) (startCircleX - curRadius * sin), (float) (startCircleY - curRadius * cos)); // B点 path.lineTo( (float) (startCircleX + curRadius * sin), (float) (startCircleY + curRadius * cos)); // C点 path.quadTo( (startCircleX + endCircleX) / 2, (startCircleY + endCircleY) / 2, (float) (endCircleX + originRadius * sin), (float) (endCircleY + originRadius * cos)); // D点 path.lineTo( (float) (endCircleX - originRadius * sin), (float) (endCircleY - originRadius * cos)); // A点 path.quadTo( (startCircleX + endCircleX) / 2, (startCircleY + endCircleY) / 2, (float) (startCircleX - curRadius * sin), (float) (startCircleY - curRadius * cos)); canvas.drawPath(path, paint); } // 绘制文字 float textH = -textFontMetrics.ascent - textFontMetrics.descent; canvas.drawText(text, endCircleX, endCircleY + textH / 2, textPaint); } else { // 非触摸状态 if (curRadius > 0) { startCircleX = curRadius; startCircleY = originHeight - curRadius; canvas.drawCircle(startCircleX, startCircleY, curRadius, paint); if (curRadius == originRadius) { // 只有在恢复正常的情况下才显示文字 // 绘制文字 float textH = -textFontMetrics.ascent - textFontMetrics.descent; canvas.drawText(text, startCircleX, startCircleY + textH / 2, textPaint); } } } // Logger.d(TAG, "circleX: " + startCircleX + ", circleY: " + startCircleY + ", // curRadius: " + curRadius); }