Hiểu khái niệm Canvas và Surface


114

Tôi đang cố gắng hiểu quá trình vẽ tới SurfaceViewvà do đó toàn bộ Surface/ Canvas/ Bitmaphệ thống, được sử dụng trong Android.

Tôi đã đọc tất cả các bài báo và các trang tài liệu về API, mà tôi có thể tìm thấy trên trang web dành cho nhà phát triển android, một vài hướng dẫn về đồ họa android, mã nguồn LunarLander và câu hỏi này .

Vui lòng cho tôi biết, câu nào trong số những câu này là đúng, câu nào không và tại sao.

  1. CanvasBitmapgắn liền với nó. SurfaceCanvasgắn liền với nó.
  2. Tất cả Viewcác cửa sổ chia sẻ như nhau Surfacevà do đó chia sẻ như nhau Canvas.
  3. SurfaceViewlà lớp con của Viewnó, không giống như các Viewlớp con khác và Viewchính nó, có lớp con riêng Surfaceđể rút vào.

Ngoài ra còn có một câu hỏi bổ sung:

  • Tại sao lại cần một Surfacelớp, nếu đã có một lớp Canvascho các hoạt động cấp cao với bitmap. Cho một ví dụ về một tình huống Canvaskhông phù hợp để làm công việc Surfacecó thể làm.

Câu trả lời:


223

Dưới đây là một số định nghĩa:

  • Bề mặt là một đối tượng chứa các pixel đang được kết hợp với màn hình. Mỗi cửa sổ bạn nhìn thấy trên màn hình (hộp thoại, hoạt động toàn màn hình của bạn, thanh trạng thái) đều có bề mặt riêng mà nó thu hút vào và Surface Flinger kết xuất chúng về màn hình cuối cùng theo đúng thứ tự Z của chúng. Một bề mặt thường có nhiều hơn một bộ đệm (thường là hai bộ đệm) để thực hiện kết xuất bộ đệm kép: ứng dụng có thể vẽ trạng thái giao diện người dùng tiếp theo của nó trong khi bộ đệm bề mặt đang kết hợp màn hình bằng bộ đệm cuối cùng, mà không cần đợi ứng dụng kết thúc đang vẽ.

  • Một cửa sổ về cơ bản giống như bạn nghĩ về một cửa sổ trên màn hình nền. Nó có một Surface duy nhất trong đó nội dung của cửa sổ được hiển thị. Một ứng dụng tương tác với Trình quản lý cửa sổ để tạo cửa sổ; Trình quản lý Cửa sổ tạo Bề mặt cho mỗi cửa sổ và đưa nó cho ứng dụng để vẽ. Ứng dụng có thể vẽ bất cứ thứ gì nó muốn trong Surface; đối với Trình quản lý cửa sổ, nó chỉ là một hình chữ nhật mờ đục.

  • Chế độ xem là một phần tử giao diện người dùng tương tác bên trong cửa sổ. Một cửa sổ có một hệ thống phân cấp dạng xem duy nhất được gắn vào nó, hệ thống này cung cấp tất cả các hành vi của cửa sổ. Bất cứ khi nào cửa sổ cần được vẽ lại (chẳng hạn như vì một chế độ xem đã vô hiệu hóa chính nó), điều này được thực hiện trong Bề mặt của cửa sổ. Surface bị khóa, nó sẽ trả về một Canvas có thể được sử dụng để vẽ vào nó. Quá trình vẽ được thực hiện theo phân cấp, đưa Canvas xuống cho mỗi chế độ xem để vẽ một phần của giao diện người dùng. Sau khi hoàn tất, Surface được mở khóa và đăng lên để vùng đệm vừa vẽ được hoán đổi sang nền trước để sau đó được Surface Flinger tổng hợp vào màn hình.

  • SurfaceView là một triển khai đặc biệt của View cũng tạo ra Surface chuyên dụng của riêng nó để ứng dụng trực tiếp vẽ vào (bên ngoài phân cấp chế độ xem thông thường, nếu không thì phải chia sẻ Surface duy nhất cho cửa sổ). Cách thức hoạt động của điều này đơn giản hơn bạn có thể mong đợi - tất cả những gì SurfaceView làm là yêu cầu trình quản lý cửa sổ tạo một cửa sổ mới, yêu cầu nó sắp xếp thứ tự Z cho cửa sổ đó ngay sau hoặc trước cửa sổ của SurfaceView và định vị nó cho khớp nơi SurfaceView xuất hiện trong cửa sổ chứa. Nếu bề mặt đang được đặt phía sau cửa sổ chính (theo thứ tự Z), SurfaceView cũng lấp đầy phần của cửa sổ chính bằng độ trong suốt để bề mặt có thể được nhìn thấy.

  • Bitmap chỉ là một giao diện cho một số dữ liệu pixel. Các pixel có thể được phân bổ bởi chính Bitmap khi bạn đang trực tiếp tạo một pixel hoặc nó có thể trỏ đến các pixel mà nó không sở hữu, chẳng hạn như những gì xảy ra trong nội bộ khi kết nối Canvas với Surface để vẽ. (Một Bitmap được tạo và trỏ đến vùng đệm bản vẽ hiện tại của Surface.)

Cũng xin lưu ý rằng, như điều này ngụ ý, SurfaceView là một vật có trọng lượng khá nặng. Nếu bạn có nhiều SurfaceView trong một giao diện người dùng cụ thể, hãy dừng lại và suy nghĩ xem điều này có thực sự cần thiết hay không. Nếu bạn có nhiều hơn hai, bạn gần như chắc chắn có quá nhiều.


Cảm ơn rât nhiều! Câu trả lời làm cho mọi thứ rõ ràng hơn. Tuy nhiên, một phần về kết nối Canvas với Surface vẫn chưa rõ ràng. Không thể tưởng tượng nơi cần hoạt động như vậy. Tiếp theo có thể lấy ví dụ về thao tác đó: vẽ Bitmap trên Canvas, có được từ SurfaceHolder với phương thức lockCanvas ()?
fyodorananiev

1
Đó là cách vẽ xảy ra Canvas là API vẽ 2d. Nếu bạn định vẽ o lên một bề mặt, bạn cần tạo một Canvas trỏ tới vùng đệm của nó để sử dụng API vẽ Canvas 2d để vẽ vào đó.
hackbod 13/10/11

6
Ngoài #hackbod'scâu trả lời, SurfaceViewcũng có thể được trả lại từ chủ đề thứ yếu mà không phải là có thể cho Viewđối tượng
Mohanraj Balasubramaniam

47

Tổng quan khái niệm về Window, Surface, Canvas và Bitmap

Đây là tổng quan khái niệm rất cơ bản và đơn giản về cách tương tác xảy ra giữa Window, Surface, Canvas và Bitmap.
Đôi khi, một biểu diễn trực quan giúp ích rất nhiều trong việc hiểu các khái niệm xoắn.
Tôi hy vọng hình ảnh này có thể giúp ai đó.


4
Visualy hình ảnh tốt hơn so với văn bản: D
mavenツ

18

Bitmap chỉ đơn giản là một trình bao bọc cho một tập hợp các pixel. Hãy coi nó như một mảng pixel với một số chức năng tiện lợi khác.

Canvas chỉ đơn giản là lớp chứa tất cả các phương thức vẽ. Nó tương tự như lớp Đồ họa trong AWT / Swing nếu bạn đã quen với điều đó. Tất cả logic về cách vẽ một hình tròn, hoặc một hộp, v.v. được chứa bên trong Canvas. Một canvas vẽ trên Bitmap hoặc một container GL đang mở nhưng không có lý do gì trong tương lai nó có thể được mở rộng để vẽ trên các loại raster khác.

SurfaceView là một Dạng xem có chứa một Bề mặt. Một bề mặt tương tự như một bitmap (nó có một kho pixel). Tôi không biết nó được thực hiện như thế nào nhưng tôi tưởng tượng nó là một loại trình bao bọc Bitmap với các phương thức bổ sung cho những thứ liên quan trực tiếp đến hiển thị màn hình (Đó là lý do cho một bề mặt, một Bitmap quá chung chung). Bạn có thể lấy Canvas từ Surface của mình, thao tác này thực sự nhận Canvas được liên kết với Bitmap bên dưới.

Những câu hỏi của bạn.

1.Canvas có Bitmap của riêng mình được gắn vào nó. Bề mặt có Canvas của riêng nó được gắn vào nó.

Có, canvas hoạt động trên Bitmap (hoặc bảng GL mở). Surface cung cấp cho bạn một Canvas đang hoạt động trên bất kỳ thứ gì Surface đang sử dụng cho cửa hàng pixel kiểu Bitmap của nó.

2. Tất cả các View của cửa sổ chia sẻ cùng một Bề mặt và do đó chia sẻ cùng một Canvas.

Không. Bạn có thể có bao nhiêu chế độ xem bề mặt tùy thích.

3.SurfaceView là lớp con của View, không giống như các lớp con khác của View và bản thân View, có Bề mặt riêng để vẽ.

Đúng. Cũng giống như ListView là một lớp con của View có cấu trúc dữ liệu Danh sách riêng của nó. Mỗi lớp con của View thực hiện một số việc khác nhau.


1
Vì vậy, BitmapSurfacechỉ là các loài khác nhau của cửa hàng pixel và Canvascó thể bọc một trong hai?
fyodorananiev

2
Về cơ bản là có. Ngoại trừ Canvas không thể ghi lên bề mặt, nó hoạt động trên bất kỳ thứ gì Surface đang sử dụng làm kho pixel của riêng nó (nếu không nhìn vào nguồn android, tôi không thể nói chắc chắn nó là gì). Nó có thể là một loại phần mở rộng Bitmap vì Canvas chỉ cung cấp các hàm tạo cho Bitmap và GL.
sksamuel

Giúp đỡ rất nhiều, cảm ơn bạn! Về câu trả lời 2. Trong câu hỏi của tôi, tôi muốn nói đến các khung nhìn tiêu chuẩn, không phải SurfaceViews. Giả sử tôi có RelativeLayout với nhiều trường và nút. Trong trường hợp này, Surface có được gắn vào toàn bộ cửa sổ và được chia sẻ bởi tất cả các Chế độ xem trong hệ thống phân cấp chế độ xem không?
fyodorananiev

1
Hãy nhớ rằng Surface chỉ là một tập hợp các pixel. Vì vậy, mỗi chế độ xem bề mặt có bề mặt riêng của nó và mỗi chế độ xem có thể được hiển thị trên một phần khác nhau của màn hình. Chúng không cần thiết phải lấp đầy màn hình (mặc dù đó là cách sử dụng phổ biến, để hiển thị đồ họa trên một trò chơi toàn màn hình).
sksamuel

1
Tôi thực sự sẽ không nghĩ về Bitmap và Surface là tương đương. Bề mặt là một đối tượng mà bề mặt nao núng, người sáng tác cửa sổ, biết về. Nghĩa là, nó là một cái gì đó có thể nhìn thấy trực tiếp trên màn hình, có một Z-trật tự trên màn hình, vv
hackbod
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.