如何在安卓系统中画一条曲线?

3

我是Android开发的新手,正在开发一个绘制线条的示例项目。我想要绘制一条连接两个点 (x1,y1 和 x2,y2) 的弯曲或升高的线条。我尝试使用 canvas.drawArc() 方法,但是 drawArc 方法中的 RectF 值只是圆的 x、y 中心点。它给出了连接两个点之间的弧线。但是我想要一条完全连接我的两个点的弯曲线条。有人可以帮帮我吗?提前感谢。


这是一个使用画布绘制的简单示例:http://www.coderzheaven.com/2013/01/10/draw-arcs-android-canvas/ - balaji koduri
2个回答

10

在onDraw方法内声明此方法:

private void drawOvalAndArrow(Canvas canvas){


    Paint circlePaint = new Paint();
    circlePaint.setStyle(Paint.Style.FILL_AND_STROKE);
    circlePaint.setAntiAlias(true);
    circlePaint.setStrokeWidth(2);
    circlePaint.setColor(Color.CYAN);

    float centerWidth = canvas.getWidth()/2; //get center x of display
    float centerHeight = canvas.getHeight()/2; //get center y of display
    float circleRadius = 20; //set radius 
    float circleDistance = 200; //set distance between both circles

    //draw circles
    canvas.drawCircle(centerWidth, centerHeight, circleRadius, circlePaint);
    canvas.drawCircle(centerWidth+circleDistance, centerHeight, circleRadius, circlePaint);


    //to draw an arrow, just lines needed, so style is only STROKE
    circlePaint.setStyle(Paint.Style.STROKE);       
    circlePaint.setColor(Color.RED);

    //create a path to draw on
    Path arrowPath = new Path();

    //create an invisible oval. the oval is for "behind the scenes" ,to set the path´
    //area. Imagine this is an egg behind your circles. the circles are in the middle of this egg
    final RectF arrowOval = new RectF();
    arrowOval.set(centerWidth, 
            centerHeight-80, 
            centerWidth + circleDistance, 
            centerHeight+80);

    //add the oval to path
    arrowPath.addArc(arrowOval,-180,180);

    //draw path on canvas
    canvas.drawPath(arrowPath, circlePaint);


    //draw arrowhead on path start
     arrowPath.moveTo(centerWidth,centerHeight ); //move to the center of first circle
     arrowPath.lineTo(centerWidth-circleRadius, centerHeight-circleRadius);//draw the first arrowhead line to the left
     arrowPath.moveTo(centerWidth,centerHeight );//move back to the center
     arrowPath.lineTo(centerWidth+circleRadius, centerHeight-circleRadius);//draw the next arrowhead line to the right

     //same as above on path end
     arrowPath.moveTo(centerWidth+circleDistance,centerHeight );
     arrowPath.lineTo((centerWidth+circleDistance)-circleRadius, centerHeight-circleRadius);
     arrowPath.moveTo(centerWidth+circleDistance,centerHeight );
     arrowPath.lineTo((centerWidth+circleDistance)+circleRadius, centerHeight-circleRadius);

     //draw the path
     canvas.drawPath(arrowPath,circlePaint);

}

同时,这将找到屏幕的两侧(横屏模式),并在屏幕上绘制完美的曲线

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    PointF mPoint1 = new PointF(w/1.2F, h/1.2F);
    PointF mPoint2 = new PointF(w/24, h/1.2F);
    Path myPath1 = new Path();
    Paint paint  = new Paint();
    paint.setAntiAlias(true);
    paint.setStyle(Style.STROKE);
    paint.setStrokeWidth(2);
    paint.setColor(Color.WHITE);

    myPath1 = drawCurve(canvas, paint, mPoint1, mPoint2);
    canvas.drawPath(myPath1, paint);

}

private Path drawCurve(Canvas canvas, Paint paint, PointF mPointa, PointF mPointb) {

    Path myPath = new Path();
    myPath.moveTo(63*w/64, h/10);
    myPath.quadTo(mPointa.x, mPointa.y, mPointb.x, mPointb.y);
    return myPath;  
}

在安卓绘图方面的有用参考资料:

如何使用画布在安卓上绘制弧线?

视图中基础绘画


1
是的。谢谢伙计。但我已经在教程中看到了这个。我检查并更改了一些参数。它起作用了。 - Surendar
1
@Surendar,你能给我那个教程的链接吗? - curiousMind

9
这可能不是您所想要的,但请查看http://developer.android.com/reference/android/graphics/Path.html,特别是moveTo、lineTo、quadTo和cubicTo。 (后两个方法将绘制贝塞尔曲线,无论是二次还是三次。如果您不知道这些是什么,请查看http://en.wikipedia.org/wiki/B%C3%A9zier_curve 您只需要理解函数的参数,而不是背后的数学原理。)对于您的目的,您可以像这样操作:
Path mPath;
Paint paint;
mPath = new Path();
mPath.moveTo(x1, y1);
mPath.cubicTo(anchor1_x, anchor1_y, anchor2_x, anchor2_y, x2, y2); /*the anchors you want, the curve will tend to reach these anchor points; look at the wikipedia article to understand more */
paint = new Paint();
paint.setColor(0xFFFFFFFF);
paint.setAntiAlias(true);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(width); //the width you want 
canvas.drawPath(mPath, paint);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接