CANVAS TRONG ANDROID
Trong Android nói chung thì tất cả các View như EditText, ImageView,.. đều được vẽ bằng canvas. Về cơ bản thì Canvas là một bề mặt phẳng giống như một tờ giấy nhưng có thể tự vẽ lên dựa trên các phương thức có sẵn.
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.
Đi thẳng vào một bài toán cụ thể như sau.
Chẳng hạn dự án chúng ta nhận được một hình ảnh là một bảng điện có các chi tiết như hình sau
Hình 1: Bảng điện A.
Vậy bây giờ chúng ta có những cách nào để tạo nên bảng điện này
- Sử dụng thẳng hình ảnh mà KH đưa :))) .
- Sử dụng View trong Android kết hợp với ConstraintLayout.
- Sử dụng canvas :>.
Cùng bắt đầu với 2 cách trước:
Cách một: dùng thẳng hình ảnh kh đưa và import vào app => cách này quá đơn giản nhưng nếu chỉ một bóng đèn hay cầu chì đổi vị trí thì chúng ta lại phải import lại ảnh và set lại cho chúng.
Cách hai: sử dụng ConstraintLayout và các view để tạo nên chúng => điều này cũng ko sao. miễn là chúng ta quản lý view tốt nhưng có lẽ mọi người quên rằng trong Android nói chung và Mobile nói riêng Một màn hình chỉ có tối đa 50 view trong khi bảng điện này có vô số cầu chì hay bóng đèn. Hoặc chỉ một điều đơn giản thế này, không có view nào hình tròn từ đầu cho chúng ta cả khi đó chúng ta sẽ phải tạo một drawable shape và set radius cho chúng.
Vậy cả 2 cách trên đều mang lại nhiều hại hơn là lợi. Chúng ta cùng nghĩ đến cách số 3.
Sử dụng canvas
Câu hỏi đặt ra là Canvas có những gì để có thể tạo nên cái bảng điện trên mà không gây ra những rắc rối về sau mà chỉ gây ra khó khăn cho dev mới tiếp cận :))).
Câu trả lời: Canvas có nhiều method hỗ trợ vẽ view nhưng cũng rất khó để bắt đầu với một dev bất kỳ :)).
Để có thể sử dụng canvas và vẽ theo ý thích của mình thì dev phải học canvas rất vất vả vì canvas sử dụng nhiều yếu tố để tạo nên 1 đường thẳng chứ không đơn giản là set width hay height.
Vậy chúng ta cùng thử sức với bản vẽ trên nhé
Trước tiên chúng ta sẽ tạo 1 View chống cho bản vẽ này và đặt tên là Electrical Panel View
và override lại hàm onDraw
Lúc này View của chúng ta chỉ là một mặt phẳng trắng
Trước khi bắt đầu chúng ta cần làm quen với Paint
Paint được sử dụng để xác định color, style, kích thước,... của đối tượng sắp được vẽ. Chúng ta có thể hiểu như sau nếu canvas là một chiếc bút thì Paint đóng vai trò là mực của chiếc bút đó
Tiếp theo chúng ta hãy bắt đầu vẽ 2 đường màu xanh và đỏ đại diện cho 2 đường điện.
Ở đây canvas cung cấp cho chúng ta method như sau
Method drawLine dùng để vẽ một đường thẳng. Cách hoạt động như sau
Đầu tiên chúng ta cần cung cấp 2 điểm nối là 2 đầu đoạn thẳng dựa trên giao cắt của trục X vs Y.
2 điểm startX và startY được đánh dấu bằng màu xanh tạo nên 1 giao cắt A
2 điểm stopX va stopY được đánh dấu bằng màu tím tạo nên 1 giao cắt B
canvas sẽ dựa vào 2 giao cắt này vẽ 1 đường nối 2 giao cắt lại.
và canvas sử dụng Paint để tô màu, tăng kích thước,... cho đường vẽ nó giống như mực của một chiếc bút vậy
tiếp theo chúng ta vẽ 2 điểm tròn màu xanh và đỏ trên bảng điện
trường hợp này thì canvas sử dụng method mới đó là drawCircle
cx và cy ở đây giao với nhau tại điểm A và điểm A được xác định là tâm hình tròn
radius: là bán kính khi canvas vẽ đường tròn đó
paint: là mực để vẽ hình tròn đó :))
Tiếp theo trong bảng điện chúng ta có một hình chữ nhật chính là cầu chì
Canvas cung cấp method để vẽ một hình chữ nhật đó là drawRect
drawRect sẽ tạo nên 4 đường thẳng giao nhau tại 4 điểm từ đó tạo nên hình chữ nhật, nếu vì lý do nào đó 4 điểm này ko đối xứng nhau, canvas sẽ không vẽ chúng
method drawRect vẽ hình chữ nhật dựa trên các params
left : đường thẳng màu đỏ cách trục y 1 khoảng
top: đường thẳng màu xanh đậm cách trục Y một khoảng
right: đường thẳng màu xanh nhạt cách trục X một khoảng
bottom: đường thẳng màu xanh lam cách trục X một khoảng
khi 4 đường thẳng này cắt nhau và các điểm đối xứng nhau Paint sẽ vẽ hình chữ nhật
các mũi tên đại diện cho khoảng cách từ các đường thẳng đến 2 trục X vs Y
cùng với tất cả các method trên chúng ta có thể triển khai vẽ bảng điện như sau
Ngay khi tạo xong Electrical Panel View thì chúng ta bắt đầu đưa chúng vào màn hình chúng ta muốn sử dụng.
Cụ thể bài toán ở đây sẽ set cứng giá trị cho View trên là 150dp cho cả width vs height:
Nhưng chúng ta thấy bản vẽ có dấu hiệu không co lại theo chiều dài và rộng của View. Điều này xuất phát từ việc chúng ta override lại hàm onDraw nhưng ko override hàm onMeasure
Vậy chúng ta cần tìm hiểu onMeasure tác động tới view như nào
onMeasure() là cơ hội để bạn nói với Android rằng bạn muốn chế độ xem tùy chỉnh của mình phụ thuộc vào các ràng buộc về bố cục do cha mẹ cung cấp như thế nào
onMeasure có các thuộc tính cơ bản sau:
- EXACTLY có nghĩa là layout_width hoặc layout_height giá trị đã được đặt thành một giá trị cụ thể.
- AT_MOST thường có nghĩa là layout_width hoặc layout_height giá trị được đặt thành match_parent hoặc wrap_content ở nơi cần kích thước tối đa (điều này phụ thuộc vào bố cục trong khuôn khổ) và kích thước của thứ nguyên mẹ là giá trị. Bạn không được lớn hơn kích thước này.
- UNSPECIFIED thường có nghĩa là layout_width hoặc layout_height giá trị được đặt thành wrap_content không có hạn chế. Bạn có thể có bất kỳ kích thước nào bạn muốn. Một số bố cục cũng sử dụng lệnh gọi lại này để tìm ra kích thước mong muốn của bạn trước khi xác định thông số kỹ thuật thực sự sẽ chuyển lại cho bạn trong yêu cầu đo thứ hai.
Tóm lược, Canvas còn rất nhiều phương thức vẽ khác mà chúng ta có thể khám phá, hi vọng qua bài viết này mọi người sẽ có thêm lựa chọn trong việc tìm kiếm giải pháp thiết kế View