Lesson 143. Drawing. Path

Lesson 143. Drawing. Path


In this lesson:

– we work with Path

In the last lesson we looked at simple figures. But apart from them, we have the ability to create complex shapes with the Path object. This object allows us to create a compound shape consisting of lines, curves, and simple shapes.

Let’s create a project:

Project name: P1431_DrawingPath
Build Target: Android 2.3.3
Application name: DrawingPath
Package name: ru.startandroid.develop.p1431drawingpath
Create Activity: MainActivity

simple figures

Kodyma in MainActivity.java:

package ru.startandroid.develop.p1431drawingpath;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(new DrawView(this));
  }

  class DrawView extends View {
    
    Paint p;
    RectF rectf;
    Path path;
    Path path1;

    public DrawView(Context context) {
      super(context);
      p = new Paint();
      p.setStrokeWidth(3);
      p.setStyle(Paint.Style.STROKE);
      
      rectf = new RectF(350,100,400,150);
      path = new Path();
      path1 = new Path();
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawARGB(80, 102, 204, 255);
      
      // очистка path
      path.reset();
            
      // угол
      path.moveTo(100, 100);
      path.lineTo(150, 200);
      path.lineTo(50, 200);
      
      // треугольник
      path.moveTo(250, 100);
      path.lineTo(300, 200);
      path.lineTo(200, 200);
      path.close();
      
      // квадрат и круг
      path.addRect(rectf, Path.Direction.CW);
      path.addCircle(450, 150, 25, Path.Direction.CW);
      
      // рисование path
      p.setColor(Color.BLACK);
      canvas.drawPath(path, p);

      
      // очистка path1
      path1.reset();
      
      // две пересекающиеся линии
      path1.moveTo(50,50);
      path1.lineTo(500,250);
      path1.moveTo(500,50);
      path1.lineTo(50,250);
      
      // рисование path1
      p.setColor(Color.GREEN);      
      canvas.drawPath(path1, p);

      
      // добавление path1 к path
      path.addPath(path1);
      
      // смещение 
      path.offset(500,100);      
      
      // рисование path
      p.setColor(Color.BLUE);      
      canvas.drawPath(path, p);
    }
    
  }
  
}

result

Let’s parse the code.

The reset method clears the path.

The moveTo method puts the cursor at the specified point. Further drawing will leave from it.

lineTo – draws a line from the current point to the specified one, the next drawing will leave already from the specified point

So we drew two straight lines, the corner came out.

Then we move the point and again draw two lines, and close the sub figure by the method close. With the moveTo method, we reported that we started drawing a new subfigure and this point is the starting point, and when we call close the line from the last point to the starting point is drawn. That is, the figure closes. So by drawing two lines and calling the close method, we got a triangle.

Next, using the addRect and addCircle methods, we add a square and a circle to the path object. The options here are the standard ones we’ve covered in our past lessons, except the last one: directions. Here are two options: Path.Direction.CW (clock-wise) and Path.Direction.CCW (clock-wise). That is, you specify the direction of drawing the lines of a square or figure. How this can be used, we will consider later.

Output the path on the screen with the same color.

Next we work with another Path object: path1. We add two intersecting lines to it. Output path1 in green. He came out on the path above us.

Now we add path1 to path with the addPath method. That is, not only shapes and lines but Path objects can be added to Path. We shift the final path 500 to the right and 100 down by the offset method, change the color to blue and print the result.

Help has some more add * methods for adding shapes that we went through in the last lesson. With them everything is similar.

curves

Path gives us the opportunity to draw not only straight lines but also curves, namely the quadratic and cubic Bezier curves. Wikipedia gives very good GIFs on this topic.

rewrite the class DrawView:

class DrawView extends View {
    
    Paint p;
    Path path;
    Point point1;
    Point point21;
    Point point22;

    public DrawView(Context context) {
      super(context);
      p = new Paint(Paint.ANTI_ALIAS_FLAG);
      p.setStrokeWidth(3);
      path = new Path();
      
      point1 = new Point(200,300);
      point21 = new Point(500,600);
      point22 = new Point(900,200);
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawARGB(80, 102, 204, 255);
      
      
      // первая линия
      p.setColor(Color.BLACK);
      canvas.drawLine(100, 100, 600, 100, p);
      
      // точка отклонения для первой линии
      p.setStyle(Paint.Style.FILL);
      p.setColor(Color.GREEN);
      canvas.drawCircle(point1.x, point1.y, 10, p);
      
      // квадратичная кривая
      path.reset();
      path.moveTo(100, 100);
      path.quadTo(point1.x, point1.y, 600, 100);
      p.setStyle(Paint.Style.STROKE);
      canvas.drawPath(path, p);
      
      
      // вторая линия
      p.setColor(Color.BLACK);
      canvas.drawLine(400, 400, 1100, 400, p);

      // точки отклонения для второй линии
      p.setStyle(Paint.Style.FILL);
      p.setColor(Color.BLUE);
      canvas.drawCircle(point21.x, point21.y, 10, p);
      canvas.drawCircle(point22.x, point22.y, 10, p);
      
      // кубическая кривая
      path.reset();
      path.moveTo(400, 400);
      path.cubicTo(point21.x, point21.y, point22.x, point22.y, 1100, 400);
      p.setStyle(Paint.Style.STROKE);
      canvas.drawPath(path, p);
    }
  }

result

Consider first green curve.

First we draw a black line (100,100) – (600,100). We only do this for the sake of clarity to see what the line would be like if we didn’t draw a curve from it.

Next we draw a small circle at the point that will be used to bend the line. We also do this just for clarity, to see in which direction the line will be curved. The coordinates of the point are specified in the point1 object.

Now we draw a curve using Path. We get to the point (100,100) by the moveTo method. The quadTo method draws a curve from the current point (100,100) to the point (600,100) (ie, the same coordinates as the black line). A point (point1.x, point1.y) allows you to specify the curve of the curve. Simply put, the curve will be rejected toward this point.

similarly we draw blue curve. Initially, the black color is a straight original. Then the point of deviation. Then it distorts. The cubicTo method draws a curve from the current point (400,400) to the point (1100,400). And the points (point21.x, point21.y) and (point22.x, point22.y) allow you to specify the curve of the curve. Simply put, the curve will be deflected toward these points.

The result shows that the curves are drawn to the points shown by the circles. For the green curve drawn by the quadTo method, this is one point. And the cubicTo method allowed us to set two such points for the blue line.

Also note that I used the Paint flag when creating the Paint object.ANTI_ALIAS_FLAG. It smooths the curves when drawing. Try to remove it and compare the result.

As a task, I suggest that you recall Lesson 102 about touching and make an application that draws a straight line, and when you touch your screen with your finger, you can twist it towards the touch point.

relative methods

The methods moveTo, lineTo, quadTo, cubicTo have the same name but start with a letter r: RMoveTo, rLineTo, rQuadTo, rCubicTo. difference r-the methods are that they use not relative, but relative (relative – hence the letter r) Coordinates.

For example, if the lineTo (100,200) method drew us a line from the current point to a point (100,200), then rLineTo (100,200) draws a line from the current point to a point that is more correct than the current one by 100 and below by 200.

Text on a figure

Now let’s see how you can use the drawing direction we put in the addRect and addCircle methods

Let’s rewrite DrawView:

class DrawView extends View {

    Paint p;
    Path path;
    String text;

    public DrawView(Context context) {
      super(context);
      p = new Paint(Paint.ANTI_ALIAS_FLAG);
      p.setStrokeWidth(1);
      p.setTextSize(20);
      path = new Path();
      text = "Draw the text, with origin at (x,y), using the specified paint";
    }

    @Override
    protected void onDraw(Canvas canvas) {
      canvas.drawARGB(80, 102, 204, 255);
      
      // черный
      path.reset();
      path.addCircle(200, 200, 100, Path.Direction.CW);
      p.setColor(Color.BLACK);
      canvas.drawTextOnPath(text, path, 0, 0, p);

      path.reset();
      path.addCircle(500, 200, 100, Path.Direction.CCW);

      // синий
      p.setStyle(Paint.Style.FILL);
      p.setColor(Color.BLUE);
      canvas.drawTextOnPath(text, path, 0, 0, p);
      p.setStyle(Paint.Style.STROKE);
      canvas.drawPath(path, p);

      // зеленый
      path.offset(-300, 250);
      p.setStyle(Paint.Style.FILL);
      p.setColor(Color.GREEN);
      canvas.drawTextOnPath(text, path, 100, 0, p);
      p.setStyle(Paint.Style.STROKE);
      canvas.drawPath(path, p);

      // красный
      path.offset(300, 0);
      p.setStyle(Paint.Style.FILL);
      p.setColor(Color.RED);
      canvas.drawTextOnPath(text, path, 0, 30, p);
      p.setStyle(Paint.Style.STROKE);
      canvas.drawPath(path, p);

    }

  }

result

We see four texts that are drawn as a circle. Let’s see how it’s done.

We add a circle to Path using the addCircle method, using the clockwise path.Direction.CW. Next, we draw with the drawTextOnPath method black color text along the path-path contour. As you can see, the text is clockwise. The circle itself is not drawn.

Next, scratch the path and add a new circle to it, using the anti-clockwise Path.Direction.CCW. It goes counter-clockwise. AND blue color draw both text and circle.

Now let’s look at the drawTextOnPath options in the green and red shapes. We will use the same path, which is drawn in blue. Only with the offset method will we move it to a new location.

In the drawTextOnPath method, the third parameter is the length of the start of the shape. IN green the circles we put this indentation at 100. It can be seen that compared to the blue circle, the text here has a circle indent from the beginning.

The fourth parameter of the drawTextOnPath method is to specify the indentation of the text from the figure. IN red when we set it to 30. And we see that the text is away from the circle outside. If you define a negative value, the text will be moved inside.

Note that Path does not use a Paint object at all. That is, Path is just a figure. And she knows nothing about the brush she will draw. The brush is set and used already directly when drawing a figure on the canvas.

In the next lesson:

– we use Matrix for geometric transformations of figures




Discuss in the forum [5 replies]
Related Posts
Lesson 190. Notifications. channels

Android Oreo (API 26) has the ability to create message channels. In this lesson we will understand how to Read more

Lesson 189. Notifications. message grouping

Android 7 (API 24) has the ability to group messages. Even if you don't explicitly implement it, the system Read more

Lesson 188. Notifications. custom messages

Android enables us to create a layout for messages ourselves. Consider a simple example: layout / notification.xml Height 64dp Read more

Lesson 187. Notifications. Action buttons. Reply.

Android 4.1 has the ability to add buttons to messages. This is done using the addAction method. Intent deleteIntent Read more

Leave a Comment