@Override protected void onDraw(Canvas canvas) { float r = CENTER_X - mPaint.getStrokeWidth() * 0.5f; canvas.translate(CENTER_X, CENTER_X); canvas.drawOval(new RectF(-r, -r, r, r), mPaint); canvas.drawCircle(0, 0, CENTER_RADIUS, mCenterPaint); if (mTrackingCenter) { int c = mCenterPaint.getColor(); mCenterPaint.setStyle(Paint.Style.STROKE); /* if (mHighlightCenter) { mCenterPaint.setAlpha(0xFF); } else { mCenterPaint.setAlpha(0x80); } */ canvas.drawCircle(0, 0, CENTER_RADIUS + mCenterPaint.getStrokeWidth(), mCenterPaint); mCenterPaint.setStyle(Paint.Style.FILL); mCenterPaint.setColor(c); } }
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // Draw the shadow canvas.drawOval(mShadowBounds, mShadowPaint); // TODO 0 Slices String label = ""; // if(mData.size() > 0) label = mData.get(mCurrentItem).mLabel; // else // label = NO_DATA_SLICE; // Draw the label text if (getShowText()) { canvas.drawText(label, mTextX, mTextY, mTextPaint); } // If the API level is less than 11, we can't rely on the view animation system to // do the scrolling animation. Need to tick it here and call postInvalidate() until the // scrolling is done. if (Build.VERSION.SDK_INT < 11) { tickScrollAnimation(); if (!mScroller.isFinished()) { postInvalidate(); } } }
private void drawBorder(Canvas canvas) { RectF rect = new RectF(getBounds()); rect.inset(borderThickness / 2, borderThickness / 2); if (shape instanceof OvalShape) { canvas.drawOval(rect, borderPaint); } else if (shape instanceof RoundRectShape) { canvas.drawRoundRect(rect, radius, radius, borderPaint); } else { canvas.drawRect(rect, borderPaint); } }
@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 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(); }
/** * 自定义的方法,简单绘制一些基本图形 * * @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); }