+2

Canvas trong Android (Phần 1)

Giới thiệu

  • Các đối tượng trên Android như TextView, EditText, ImageView đều được vẽ trên canvas của hệ thống Android. Vậy vẽ các các đối tượng này như thế nào thì bài viết này sẽ cùng các bạn làm rõ.

Canvas là gì

  • Canvas được xem như là một bền mặt (hình dung như tờ giấy, bảng) mà chúng ta có thể vẽ bất cứ thứ gì lên đó. Ví dụ như vẽ một điểm, đường thằng, hình chữ nhật, đường tròn, elip, văn bản, hay thậm chí là một hình ảnh và các hình ảnh phức tạp khác nữa.

Canvas có thể làm những gì?

  • Trong Android nếu bạn muốn tạo một view với và tự vẽ lại tất cả các thành phần của view đó thì một điều chắc chắn rằng bạn phải sử dụng canvas.

  • Canvas trong Android có cung cấp cho chúng ta các method để vẽ tất cả các đối tượng như sau:

Các đối tượng hình học cơ bản (point, line, oval, rect..)


Vẽ hình ảnh (bitmap, drawable) Vẽ Path (Tập hợp các điểm) Vẽ Text


  • Những thành phần mà chúng ta vẽ đều được xử lý trong phương thức onDraw(Canvas canvas) của class View. Và để vẽ những đối tượng, thành phần lên Canvas chúng ta phải cần sử dụng một đối tượng Paint để định dạng Style, color, size cho net vẽ. Chi tết về Paint sẽ đề cập ngay ở phần dưới bài viết.

Chúng ta có thể tìm hiểu chi tiết về class Canvas.java ở ngay tại đây.

  • Trong 2 bài viết về canvas trong Android chúng ta sẽ tìm hiểu từ cơ bản tới chuyên sâu về nó, để giúp các bạn có thể vẽ bất cứ thứ gì trên canvas.

Khởi tạo project làm việc với canvas

  • Trước khi bắt đầu vào tìm hiểu canvas chúng ta tạo project để thực hành. Ở đây tôi tạo project có tên là CanvasDemo

Bắt đầu tạo project trong android studio

  • Trong đó tiến hành tạo class GraphicView kế thừa từ class View để vẽ các thành phần trong View này.
package com.example.canvasdemo;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;

public class GraphicView extends View  {
    public GraphicView(Context context) {
        this(context, null);
    }
 
    public GraphicView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
 
    public GraphicView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
 
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //Draw component in here
    }
}

  • Trong file activity_main.xml chúng ta thêm GraphicView với width và height match_parent để có không gian rộng hiển thị các hình học mà chúng ta vẽ.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.canvasdemo.MainActivity">
 
    <com.example.canvasdemo.GraphicView
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</FrameLayout>

Paint

Giới thiệu đối tượng Paint

  • Paint trong java dùng để định nghĩa size, color, kiểu nét vẽ mà chúng ta sẽ sử dụng để vẽ bởi canvas (truyền vào method cavas.draw… trong phương thức onDraw của View).

Các method của class Paint

  • Trước tiên chúng ta có 2 cách khởi tạo Paint

Cách 1: Contructor không có đối số

Paint mPaint = new Paint();

Cách 2: Contructor có hai đối số

Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
  • Biến cờ truyền vào ở trên chỉ định cho Paint rằng vẽ smooth các biên của các đối tượng. Ví dụ như vẽ hình tròn sẽ loại bỏ những hình răng cưa bao quanh hình tròn từ đó có cảm giác hình vẽ lên mượt mà hơn.

Và dưới đây là các phương thức được sử dụng phổ biến.

  • setColor(int color); Set màu cho nét vẽ.

  • setAlpha(int a); Set giá trị Alpha cho nét vẽ. Chỉ chấp nhận các giá trị từ 0 đến 255. Thường sử dụng để làm animation fade in và fade out.

  • setStrokeWidth(float width); Set giá trị độ rộng của net vẽ.

  • setStyle(Style style); Set style cho nét vẽ. Có ba giá trị như sau:

  • Paint.Style.FILL: Kiểu này dùng để tô đối tượng, ví dụ như tô hình tròn, elip, oval.

  • Paint.Style.STROKE. Kiểu này dùng để vẽ đường. ví dụ như vẽ đường tròn mà không có tô.

  • **Paint.Style.FILL_AND_STROKE:**Kiểu vừa vẻ vừa tô.

  • setStrokeCap(Cap cap); Set style vẽ ở những điểm kết thúc của hai đường thẳng và có những giá trị sau:

  • Cap.ROUND: Bo tròn nét vẽ ở hai đầu mút của đoạn thẳng.

  • Cap.SQUARE: Vẽ nét vẽ bình thường. Nét vẽ sẽ sắc cạch ở hai đầu mút của đoạn thẳng.

  • setTypeface(Typeface typeface); Set kiểu phong cho nét vẽ, sử dụng trong trường hợp chúng ta muốn vẽ text.

  • setTextSize(float textSize); set font size cho nét vẽ, sử dụng trong trường hợp vẽ text.

  • Trên đây tôi đã giới thiệu chi tiết về đối tượng Paint. Những method tôi giới thiệu trên đây được sử dụng khá nhiều trong quá trình các bạn vẽ hình học lên trên canvas. Và bây giờ chúng ta sẽ đi nhanh vào phần chính đó là vẽ các đối tượng hình học lên canvas.

Vẽ các đối tượng cơ bản bằng canvas

  • Canvas có cung cấp cho chúng ta rất nhiều các phương thức để chúng ta vẽ các đối tượng hình học bắt đầu bởi phương thức cavas.draw…

    alt

  • Trong bài viết phần này tôi chỉ giới thiệu vẽ một số hình học cơ bản dưới đây


Draw Point Draw Line Draw Rect Draw Circle Draw Ovals Draw Arc


  • Và những đối tượng khác và các tính năng nâng cao về canvas sẽ được giới thiệu ở bài viết sau.

  • Trước tiên tôi tạo một đối tượng Paint và set các thuộc tính phục vụ cho mục đích vẽ của tôi.

 private void initPaint() {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(Color.BLUE);
        mPaint.setStrokeWidth(30);
  }
  • Màu sử dụng để vẽ là màu xanh BLUE, độ rộng nét vẽ là 30.
  • Và đặt vào trong contructor thứ ba của GraphicView.
public GraphicView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaint();
 }

Draw Point

  • Các phương thức để vẽ Point trên canvas

drawPoint(float x, float y, @NonNull Paint paint)

  • Vẽ điểm tại đoạ độ x, y sử dụng đối tượng paint để vẽ.

drawPoints(@NonNull float[] pts, @NonNull Paint paint)

  • Vẽ danh sách các điểm trong mảng pts hai vị trí kề này là x và y. Và sử dụng đối tượng paint để vẽ.

drawPoints(float[] pts, int offset, int count, @NonNull Paint paint)

  • Vẽ danh sách các điểm trong mảng pts và có giới hạn vẽ từ khoảng nào và độ dài là bao nhiêu.

Ví dụ muốn vẽ một điểm ở vị trí x = 100, y = 100 chúng ta làm như sau.

    //Draw Point
     int x = 100;
     int y = 200;
     canvas.drawPoint(x, y, mPaint); 

**Kết quả: **
alt

Draw Line

  • Các phương thức để vẽ line trên canvas:

drawLine(float startX, float startY, float stopX, float stopY, Paint paint)

  • Vẽ đoạn thẳng với 4 tham số là điểm x bắt đầu, điểm y bắt đầu, điểm x kết thúc, điểm y kết thúc.

drawLines(float[] pts, int offset, int count, Paint paint)

  • Vẽ đoạn thẳng trong mảng pts với 4 phần tử liên tiếp sẽ là startX, startY, stopX, stopY với độ dời offset bao nhiêu trong mảng và số phần tử để vẽ.

drawLines(float[] pts, Paint paint)

  • Vẽ đoạn thẳng trong mảng pts với 4 phần tử liên tiếp sẽ là startX, startY, stopX, stopY sử dụng paint để vẽ.

Ví dụ tối muốn vẽ đường chéo từ góc trái màn hình qua góc phải màn hình sẽ làm như sau

       //Draw Line
        float startX = 0;
        float startY = 0;
        float stopX = getWidth();
        float stopY = getHeight();
 
        canvas.drawLine(startX, startY, stopX, stopY, mPaint);

**Kết quả: **
alt

Draw Rect

  • Các phương thức vẽ Rect mà canvas hổ trợ

drawRect(@NonNull RectF rect, @NonNull Paint paint)

  • Vẽ Rect với data rect là kiểu số thực.

drawRect(@NonNull Rect r, @NonNull Paint paint)

  • Vẽ rect với data r là số nguyên

drawRect(float left, float top, float right, float bottom, @NonNull Paint paint)

  • Vẽ Rect với các thông số cơ bản left, top, right, bottom.

Ví dụ muốn vẽ Rect có width = 100 và height = 200 ở chính giữa màn hình như sau:

        //Draw Rect
        float width = 100;
        float height = 200;
 
        float left = (getWidth() - width) / 2.0f;
        float top = (getHeight() - height) / 2.0f;
        canvas.drawRect(left, top, left + width, top + height, mPaint);

Kết quả:
alt

  • Bây giờ chúng ta thử set Paint như dưới đây, chạy lại và thấy kết quả như sau
      mPaint.setStyle(Paint.Style.STROKE);  

alt

Draw Circle

  • Chúng ta chỉ có duy nhất một phương thức để vẽ Circle

drawCircle(float cx, float cy, float radius, @NonNull Paint paint)

  • Với 4 tham số lần lượt là toạ độ tâm x, toạ độ tâm y, bán kính của circle và cuối cùng là paint sử dụng để vẽ.

Ví dụ tiếp thep tôi sẽ vẽ hình tròn có bán kính là 50 ở góc trái trên:

        //Draw Circle
        float radius = 50.0f;
        float cx = radius;
        float cy = radius;
        canvas.drawCircle(cx,cy,radius,mPaint);

Kết quả:

alt

Draw Oval

  • Các phương thức sử dụng để vẽ hình Oval.

drawOval(float left, float top, float right, float bottom, @NonNull Paint paint)

  • Vẽ hình oval có các yếu tố là left, top, right, bottom, và sử dụng paint để vẽ.

drawOval(@NonNull RectF oval, @NonNull Paint paint)

  • Vẽ hình oval trong hình chữ nhật có các yếu tố là left, top, right, bottom, và sử dụng paint để vẽ. Phương thức này chỉ gọi được trên Android API 21.

Ví dụ này sẽ vẽ hình oval chính giữa màn hình:

alt

Draw Arc

  • Đây là hình học cuối cùng mà tôi giới thiệu trong bài viết này. Chúng ta có các phương thức đễ vẽ Arc lên canvas.

drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint)

  • Vẽ Arc với các đối số. Hình chữ nhật bao quanh, góc bắt đầu vẽ, cung vẽ bao nhiêu, có sử dụng tâm để vẽ và paint để có thể vẽ lên canvas.

drawArc(float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint)

  • Vẽ Arc với các đối số left, top, right, bottom đại diện cho hình chữ nhật bao quanh arc, góc bắt đầu vẽ, cung vẽ bao nhiêu, có sử dụng tâm để vẽ và paint để có thể vẽ lên canvas. Phương thức này chỉ sử dụng được trên Android API hoặc API lớn hơn.

Ví dụ vẽ hình Arc ở giữa màn hình thiết bị với các thông số là góc bắt đầu vẽ có giá trị 45 và chiều dài cung vẽ là 270.

       //Draw Arc
       float width = 400;
       float height = 400;

       float left = (getWidth() - width) / 2.0f;
       float top = (getHeight() - height) / 2.0f;
       canvas.drawArc(new RectF(left, top, left + width, top + height),45, 270, false, mPaint);

alt

** Bây giờ chúng ta set thuộc tính paint như sau**

    mPaint.setStyle(Paint.Style.STROKE);

Run lại sẽ thấy như sau.

alt

Set thêm thuộc tính dưới đây cho paint.

    mPaint.setStyle(Paint.Style.STROKE);

alt

Nếu xét thêm đoạn code này bạn sẽ thấy 1 hình ảnh của 1 game trẻ thơ mà mình chơi nào đó . 😃

      float width = 400;
      float height = 400;

      float left = (getWidth() - width) / 2.0f;
      float top = (getHeight() - height) / 2.0f;
      canvas.drawArc(new RectF(left, top, left + width, top + height),45, 270, true, mPaint);

Các bạn thấy hai đầu mút được bo tròn lại đúng không nào. Đó là tác dụng của Paint.Cap.Round.

Kết luận

  • Trong bài viết này tôi đã giới thiệu cho các bạn về Canvas là gì, Canvas có thể làm được những việc gì. Tìm hiểu đối tượng Paint để set các thuộc tính trước khi vẽ lên Canvas cũng như vẽ một số hình học cơ bản lên trên canvas sử dụng Paint. Bài viết Canvas trong Android (Phần 2) sẽ giới thiệu vẽ các thành phần khác như vẽ bitmap, vẽ text, vẽ drawable, và các tính năng nâng cao khi sử dụng canvas. Nếu có thắc mắc nào trong bài viết này các bạn để lại comment bên dưới để tôi giải đáp và khắc phục vấn đề của các bạn. Hẹn gặp lại các bạn trong bài viết tiếp theo.

2d graphics trong android, cách sử dụng canvas trong android, canvas in android, canvas trong android, paint trong android, su dung canvas trong android


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí