Chuyển đến nội dung chính

Getting Started with Android Canvas Drawing

 


Lặn sử dụng lớp Android Canvas có thể mở khóa siêu năng lực ma thuật mà bạn chưa từng biết mình có. Hãy tưởng tượng bạn có thể vẽ bất cứ thứ gì * mà trái tim bạn mong muốn chỉ với một số hình dạng, đường dẫn và bitmap cơ bản? Vâng, Android Canvas chỉ cung cấp cho bạn khả năng đó.

1. What is a Canvas?

Canvas là một lớp trong Android thực hiện việc vẽ 2D các đối tượng khác nhau lên màn hình. Câu nói “a blank canvas” rất giống với đối tượng Canvas trên Android. Về cơ bản, nó là một không gian trống để vẽ vào.

Mẹo: Kiểm tra mã nguồn SKIA để hiểu sâu hơn về việc triển khai Canvas.

Rất hữu ích khi biết rằng SKIA được sử dụng trong mã cơ bản cho Android, vì vậy khi bạn

gặp khó khăn khi cố gắng hiểu cách hoạt động của một API nhất định, bạn có thể xem

mã nguồn dành cho SKIA để hiểu sâu hơn.

2. Canvas Coordinate System


Hệ tọa độ của canvas Android bắt đầu ở góc trên cùng bên trái, trong đó [0,0] đại diện cho

điểm đó. Trục y dương hướng xuống và trục x dương hướng sang phải.


Tất cả các phần tử được vẽ trên canvas được đặt tương ứng với điểm [0,0].


Khi làm việc với Canvas, bạn đang làm việc với px chứ không phải dp, vì vậy bất kỳ

phương pháp nào như dịch hoặc thay đổi kích thước sẽ được thực hiện ở kích thước

pixel. Điều này có nghĩa là bạn cần dịch bất kỳ giá trị dp nào thành px trước khi gọi bất kỳ

hoạt động canvas nào. Điều này sẽ đảm bảo rằng bản vẽ của bạn trông nhất quán trên các

thiết bị có mật độ pixel khác nhau.

Các lệnh vẽ canvas sẽ vẽ lên các mục đã vẽ trước đó. Lệnh vẽ cuối cùng sẽ là mục trên cùng được vẽ trên canvas của bạn. Việc đảm bảo rằng các mục của bạn được bố trí chính xác là tùy thuộc vào bạn (Ngoài ra, bạn có thể muốn sử dụng một số cơ chế bố cục tích hợp cho việc này - chẳng hạn như LinearLayout).

3. How do I use a Canvas?

Để vẽ lên canvas trong Android, bạn sẽ cần bốn thứ:

  • Một bitmap hoặc một khung nhìn - để giữ các pixel nơi canvas sẽ được vẽ.

  • Canvas - để chạy các lệnh vẽ trên.

  • Lệnh vẽ - để chỉ cho canvas những gì cần vẽ.

  • Paint - để mô tả cách vẽ các lệnh.


4. Get access to a Canvas instance


Để có quyền truy cập vào một phiên bản Canvas, bạn sẽ cần tạo một lớp mở rộng từ View.

Sau đó, điều này sẽ cho phép bạn ghi đè phương thức onDraw, phương thức này có

Canvas làm tham số.


class CustomView @JvmOverloads constructor(context: Context,
attrs: AttributeSet? = null, defStyleAttr: Int = 0)
: View(context, attrs, defStyleAttr) {


// Called when the view should render its content.
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
// DRAW STUFF HERE
}
}

Sau đó, bạn có thể đưa chế độ xem này vào bên trong XML bố cục của mình và sau đó nó sẽ tự động gọi phương thức onDraw của Chế độ xem tùy chỉnh.

<za.co.riggaroo.customviews.CustomView
android:layout_width="200dp"
android:layout_height="300dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>

Bạn cũng có thể có quyền truy cập vào đối tượng Canvas bằng cách tạo lập trình một đối tượng trong mã, như sau:


val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)

Tại thời điểm này, cần lưu ý rằng bất kỳ Canvas nào được tạo theo chương trình mà không sử dụng View, sẽ được kết xuất phần mềm chứ không phải phần cứng. Điều này có thể ảnh hưởng đến sự xuất hiện của một số lệnh vẽ. Ví dụ: một số lệnh không được hỗ trợ với kết xuất phần cứng hoặc chỉ được hỗ trợ từ một cấp API nhất định. Để biết thêm thông tin về sự khác biệt giữa kết xuất phần cứng và kết xuất phần mềm, hãy đọc bài đăng này.


5. What can I draw on a Canvas?


Có rất nhiều thứ khác nhau mà bạn có thể vẽ lên Canvas. Một trong những thao tác vẽ phổ biến nhất là vẽ một bitmap (hình ảnh) lên canvas. Phương pháp để thực hiện việc này chỉ được gọi là drawBitmap và nó sử dụng đối tượng bitmap được tải lên bằng các cơ chế tích hợp của Android hoặc bằng Glide.


canvas.drawBitmap(bitmap, null, rect, paint)

Tham số thứ hai ở đây cho phép chúng ta chuyển vào một phần của bitmap mà bạn muốn kết xuất, khi truyền vào null, toàn bộ bitmap sẽ được hiển thị. Tham số thứ ba là một đối tượng RectF đại diện cho tỷ lệ và bản dịch của bitmap mà bạn muốn vẽ trên màn hình.


Mẹo: Đảm bảo rằng đối tượng RectF mà bạn chuyển vào hàm drawBitmap được chia tỷ lệ với tỷ lệ khung hình chính xác, nếu không đầu ra của bạn có thể bị kéo giãn.


Bạn cần phải cẩn thận với điều này, vì nó có thể khá dễ dàng kéo giãn bitmap, vì các lệnh gọi Canvas không tính đến tỷ lệ co của hình ảnh được cung cấp. Bạn cần đảm bảo trực tràng được đưa vào đúng tỷ lệ. Tham số thứ tư là đối tượng paint, chúng tôi sẽ trình bày về mục đích của tham số này ngay sau đây.


Có nhiều phương pháp vẽ Canvas khác có thể cung cấp cho bạn một số góc nhìn tuyệt vời. Chúng tôi sẽ không trình bày tất cả ở đây, nhưng đây là hai ví dụ khác về các phương pháp vẽ trên lớp Canvas:


Để vẽ một vòng tròn lên khung nhìn, hãy cung cấp cho nó một điểm chính giữa x, y, size and apaint object:


canvas.drawCircle(x, y, size, paint)

Một phương thức khác là phương thức drawRect(). Thao tác này vẽ một hình chữ nhật trên màn hình:

canvas.drawRect(rect, paint)

Đây không phải là danh sách đầy đủ các phương pháp vẽ nhưng chỉ là một điểm nhấn nhỏ của một số phương pháp để giúp bạn hiểu rõ hơn về các khái niệm, vui lòng duyệt qua tài liệu Canvas để có danh sách toàn diện về tất cả chúng.


6. Paint


Theo tôi, lớp Paint có thể là lớp đồ họa thú vị nhất và nó cũng là lớp yêu thích của tôi, vì lý do đó. Có quá nhiều thứ mà một đối tượng Paint có thể làm được, điều đó có thể thực sự làm cho các thao tác vẽ của bạn trở nên tỏa sáng.


Lớp Paint thường chứa thông tin về màu sắc và kiểu dáng. Đối tượng Paint sau đó được sử dụng để vẽ các đối tượng (tức là bitmap, văn bản, đường dẫn, v.v.) lên Canvas.


Để tạo một đối tượng Paint:


private val textPaint =
Paint().apply {
isAntiAlias = true
color = Color.RED
style = Paint.Style.STROKE
}

Đối tượng này nên được tạo trước khi sử dụng nó trong Canvas#onDraw(). Bạn không nên tạo nó trong onDraw() vì bạn không nên thực hiện phân bổ đối tượng trong phương thức đó.


Mẹo: Sử dụng cờ isAntiAlias để đảm bảo bản vẽ của bạn có các cạnh mịn.


Cờ isAntiAlias là một cờ khá quan trọng. Nếu bạn đang vẽ các đối tượng vào canvas của mình và bạn nhận thấy rằng các cạnh của đối tượng của bạn có các cạnh răng cưa, có khả năng là bạn chưa đặt cờ này thành true. Cờ này biểu thị cho sơn để làm mịn các cạnh của đối tượng bạn đang vẽ vào khung vẽ.


Lớp Paint không chỉ có ba thuộc tính đó, bạn có thể làm nhiều thứ hơn nữa với nó. Ví dụ: bạn cũng có thể đặt các thuộc tính liên quan đến kết xuất văn bản, chẳng hạn như kiểu chữ, letterSpacing (kerning) và textSize.


private val textPaint =
Paint().apply {
isAntiAlias = true
textSize = fontSize
letterSpacing = letterSpace
typeface = newTypeface
setShadowLayer(blurValue, x, y, Color.BLACK)
}

Mẹo: Kiểm tra xem các API Canvas/Paint bạn đang sử dụng có hoạt động trên các phiên bản API khác nhau hay không. Xem trang web này để biết thêm thông tin.


Cần lưu ý rằng phương thức Paint # setShadowlayer() không hoạt động nhất quán trên các cấp API và lệnh vẽ. Nó hoạt động khi vẽ văn bản trên Canvas, nhưng việc áp dụng bóng cho các lệnh khác như drawBitmap không mang lại kết quả giống nhau trên các cấp API.


Lý do cho sự không nhất quán giữa các cấp API là do các API Canvas được đóng gói với Nền tảng Android và do đó không được cập nhật cho đến khi hệ điều hành được cập nhật. Xem danh sách trên trang này để biết thêm thông tin về các API nào hoạt động trên các phiên bản Android.


Khi bạn đã tạo đối tượng Paint, hãy chuyển đối tượng đó vào lệnh gọi Canvas#draw*() của bạn và bản vẽ sau đó sẽ sử dụng các thuộc tính mà bạn đã chỉ định trong paint.


7. Next up…


Trong một vài bài viết tiếp theo, chúng ta sẽ đi sâu vào các phần khác của việc làm việc với Canvas và vẽ trên Android.


8. References:


Android Canvas Documentation

Mozilla HTML Canvas Documentation



Nhận xét

Bài đăng phổ biến từ blog này

Jetpack Compose VS SwiftUI !VS Flutter

  Việc phát triển Android đã trở nên dễ dàng hơn khi các bản cập nhật liên tục đến. Sau bản cập nhật 2020.3.1, rất nhiều thứ đã thay đổi. Nhưng thay đổi chính mà tôi nghĩ hầu hết các nhà phát triển phải chờ đợi là Jetpack Compose cho ứng dụng sản xuất. Và Kotlin là lựa chọn duy nhất cho jetpack Compose, cũng là ngôn ngữ được ưu tiên. Để biết thêm chi tiết hoặc các thay đổi trên Jetpack Compose, bạn có thể truy cập vào https://developer.android.com/jetpack/compose Tương tự, IOS Development cũng cung cấp một tùy chọn để phát triển khai báo, SwiftUI. Trong IDE, không có thay đổi nào do điều này. Nhưng khái niệm gần giống với Jetpack Compose. Thay vì bảng phân cảnh, chúng tôi tạo giao diện người dùng bằng Swift. Để biết thêm chi tiết hoặc các thay đổi trên SwiftUI, hãy truy cập https://developer.apple.com/xcode/swiftui/ Hãy xem cách cả hai hoạt động bằng cách sử dụng một dự án demo. Tôi đã lấy một số ví dụ về số lần chạm tương tự của Flutter. 1. Android Jetpack Compose Chúng tôi có thể tạo

Thiết kế giao diện với DotNetBar (Phần 1)

Đây là phiên bản DotNetBar hỗ trợ C# và Visual Basic https://www.dropbox.com/s/wx80jpvgnlrmtux/DotNetBar.rar  , phiên bản này hỗ trợ giao diện Metro cực kỳ “dễ thương” Các bạn load về và cài đặt, khi cài đặt xong sẽ có source code mẫu của tất cả các control. Để sử dụng được các control của DotNetBar các bạn nhớ add item vào controls box. Thiết kế giao diện với DotNetBar, giao diện sẽ rất đẹp. Link các video hướng dẫn chi tiết cách sử dụng và coding: http://www.devcomponents.com/dotnetbar/movies.aspx Hiện tại DotNetBar có rất nhiều công cụ cực mạnh, trong đó có 3 công cụ dưới đây: DotNetBar for Windows Forms Requires with Visual Studio 2003, 2005, 2008, 2010 or 2012.   DotNetBar for WPF Requires with Visual Studio 2010 or 2012 and Windows Presentation Foundation.   DotNetBar for Silverlight Requires with Visual Studio 2010 or 2012 and Silverlight. Dưới đây là một số hình ảnh về các control trong DotnetBar.   Metro User Interface  controls with Metro Tiles, toolbars, slide panels, forms,

Một số bài tập Winform C#

Một số bài tập: 1. Mô phỏng game đoán số. Luật chơi:         o Đúng số và đúng vị trí   +         o Đúng số mà sai vị trí      ?         o Sai số và sai vị trí          -         . . .         - Kết quả được tạo ngẫu nhiên từ các số có 4 chữ số.         - Các chữ số có giá trị từ 0-6.         - Người chơi có 6 lần đoán. Chương trình tham khảo: 2. In số điện tử Yêu cầu: người dùng nhập vào 1 số ( hoặc 1 chuỗi số) yêu cầu in ra số đó dưới dạng số điện tử. Chương trình tham khảo: 3. Mô phỏng game CARO  (update) 4. Mô phỏng game DÒ MÌN (update)