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 ...
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 awidth 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_awidth="match_parent" android:layout_height="match_parent" tools:context="com.example.canvasdemo.MainActivity"> <com.example.canvasdemo.GraphicView android:layout_awidth="match_parent" android:layout_height="match_parent" /> </FrameLayout>
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 awidth); 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.
-
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…
-
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(); }
- 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ả: **
- 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ả: **
- 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ó awidth = 100 và height = 200 ở chính giữa màn hình như sau:
//Draw Rect float awidth = 100; float height = 200; float left = (getWidth() - awidth) / 2.0f; float top = (getHeight() - height) / 2.0f; canvas.drawRect(left, top, left + awidth, top + height, mPaint);
Kết quả:
- 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);
- 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ả:
- 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:
- Đâ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 awidth = 400; float height = 400; float left = (getWidth() - awidth) / 2.0f; float top = (getHeight() - height) / 2.0f; canvas.drawArc(new RectF(left, top, left + awidth, top + height),45, 270, false, mPaint);
** 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.
Set thêm thuộc tính dưới đây cho paint.
mPaint.setStyle(Paint.Style.STROKE);
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 đó .