Розуміння понять "Полотно та поверхня"


114

Я намагаюся зрозуміти процес малювання SurfaceViewі, отже, цілу Surface/ Canvas/ Bitmapсистему, яка використовується в Android.

Я прочитав усі статті та сторінки документації API, які мені вдалося знайти на сайті розробників Android, кілька навчальних посібників з андроїд графікою, вихідний код LunarLander та це запитання .

Скажіть, будь ласка, які з цих тверджень є правдивими, а які - ні.

  1. Canvasмає свою Bitmapприв’язану до нього. Surfaceмає свою Canvasприв’язану до нього.
  2. Усі Viewвікна діляться однаковими Surfaceі, таким чином, поділяють одне і те ж Canvas.
  3. SurfaceViewце підклас View, який, на відміну від інших Viewпідкласів і Viewсамого себе, має власноруч Surfaceмалювати.

Також є ще одне додаткове запитання:

  • Чому потрібен Surfaceклас, якщо вже є Canvasоперації високого рівня з растровою картою. Наведіть приклад ситуації, коли Canvasне підходить для роботи, яка Surfaceможе виконувати.

2
Графічна архітектура doc: source.android.com/devices/graphics/architecture.html
вівторок

Відповіді:


223

Ось кілька визначень:

  • Поверхня - це об'єкт, що містить пікселі, які компонуються на екрані. Кожне вікно, яке ви бачите на екрані (діалогове вікно, ваша повноекранна активність, рядок стану), має власну поверхню, на яку вона втягується, і Surface Flinger переводить їх на остаточне відображення у правильному Z-порядку. Поверхня, як правило, має більше одного буфера (зазвичай два) для здійснення подвійного буферизації: додаток може малювати наступний стан інтерфейсу, поки поверхневий флінгер компонує екран за допомогою останнього буфера, не потрібно чекати завершення програми малюнок.

  • Вікно в основному таке, як ви думаєте про вікно на робочому столі. Він має єдину поверхню, в якій відображається вміст вікна. Додаток взаємодіє з Менеджером вікон для створення вікон; менеджер вікон створює Поверхня для кожного вікна і надає його додатку для малювання. Додаток може малювати все, що хоче в Поверхні; для менеджера вікон це просто непрозорий прямокутник.

  • Вид - це інтерактивний елемент інтерфейсу користувача всередині вікна. До вікна додається єдина ієрархія перегляду, яка забезпечує всю поведінку вікна. Кожен раз, коли вікно потрібно переробити (наприклад, через те, що представлення недійсне), це робиться в Поверхню вікна. Поверхня заблокована, що повертає Полотно, яке можна використовувати для малювання. Проїзд малюнка робиться вниз по ієрархії, передаючи полотно вниз для кожного виду, щоб намалювати свою частину інтерфейсу користувача. Після завершення поверхня розблоковується та розміщується так, щойно намальований буфер поміняється на передній план, щоб потім його скласти на екран Surface Flinger.

  • SurfaceView - це спеціальна реалізація View, яка також створює власну виділену поверхню для додатка для прямого залучення (за межами звичайної ієрархії перегляду, яка в іншому випадку повинна розділяти єдину поверхню для вікна). Те, як це працює, простіше, ніж ви можете очікувати - все SurfaceView - це попросити менеджера вікон створити нове вікно, повідомивши це Z-замовити це вікно безпосередньо за або перед вікном SurfaceView, і розташувавши його так, щоб він відповідав де SurfaceView відображається у вікні, що містить. Якщо поверхня розміщується за головним вікном (у порядку Z), SurfaceView також заповнює свою частину головного вікна прозорістю, щоб її можна було побачити.

  • Растрова карта - це лише інтерфейс до деяких піксельних даних. Пікселі можуть бути виділені самим Bitmap, коли ви безпосередньо створюєте його, або він може вказувати на пікселі, які йому не належать, наприклад, те, що відбувається внутрішньо, щоб підключити полотно до поверхні для малювання. (Створюється Bitmap і вказується на поточний буфер малюнка Поверхні.)

Також пам’ятайте, що, як це випливає, SurfaceView є досить важким об’єктом. Якщо у вас є кілька SurfaceView в певному інтерфейсі, зупиніться і подумайте, чи справді це потрібно. Якщо у вас більше двох, ви майже напевно їх занадто багато.


Велике спасибі! Відповідь зробила речі зрозумілішими. Хоча частина щодо підключення полотна до поверхні не зрозуміла. Не уявляю, де потрібна така операція. Чи може бути наступним прикладом цієї операції: малювання Bitmap на полотні, придбаному з SurfaceHolder методом lockCanvas ()?
фьодорананьєв

1
Ось як відбувається малювання Canvas - це 2d API малювання. Якщо ви збираєтеся малювати o до поверхні, вам потрібно зробити Canvas, який вказує на його буфер, щоб використовувати API для малювання Canvas 2d для залучення до нього.
hackbod

6
Окрім #hackbod'sвідповіді, SurfaceViewтакож може бути відображено з вторинної нитки, яка неможлива для Viewоб’єктів
Mohanraj Balasubramaniam

47

Концептуальний огляд вікон, поверхні, полотна та растрових зображень

Ось дуже базовий та простий концептуальний огляд того, як відбувається взаємодія між вікном, поверхнею, полотном та растровою картиною.
Іноді наочне уявлення дуже допомагає в розумінні скручених понять.
Я сподіваюся, що ця графіка може комусь допомогти.


4
Візуальні зображення краще, ніж текст: D
Maveň ツ

18

Растрова карта - це просто обгортка для колекції пікселів. Подумайте про це як масив пікселів з деякими іншими зручними функціями.

Полотно - це просто клас, який містить усі методи малювання. Це аналогічно класу Graphics в AWT / Swing, якщо ви знайомі з цим. Вся логіка щодо того, як намалювати коло, коробку тощо, міститься всередині Canvas. Полотно малюється на Bitmap або відкритому контейнері GL, але немає причин, чому в майбутньому його можна було б розширити, щоб намалювати інші типи растра.

SurfaceView - це вид, який містить поверхню. Поверхня схожа на растрову карту (у ній зберігається піксель). Я не знаю, як це реалізовано, але я б уявив, що це якась обгортка Bitmap з додатковими методами для речей, безпосередньо пов'язаних з екранами (Це причина поверхні, а Bitmap занадто загальний). Ви можете отримати полотно зі своєї поверхні, яка дійсно отримує полотно, пов'язане з базовою растровою картиною.

Ваші запитання.

1.Canvas має власну Bitmap, приєднану до нього. На поверхні є прикріплене власне полотно.

Так, полотно працює на Bitmap (або відкритій панелі GL). Surface надає полотно, яке працює на будь-якій поверхні, яка використовується для свого піксельного магазину в стилі Bitmap.

2.Всі огляди вікон поділяють ту саму Поверхню і таким чином ділять одне й те саме полотно.

Ні. У вас може бути стільки видів поверхонь, скільки ви хочете.

3.SurfaceView - підклас View, який, на відміну від інших підкласів View і самого View, має власну поверхню для залучення.

Так. Так само, як ListView - це підклас View, який має власну структуру даних списку. Кожен підклас View робить щось інше.


1
Отже, Bitmapа чи Surfaceє лише різні види магазину пікселів і чи Canvasможна обернути будь-який із них?
фьодорананьєв

2
В основному так. За винятком того, що Canvas не може писати на поверхню, він працює на будь-якій поверхні, яка використовується як власний магазин пікселів (не дивлячись на джерело андроїда, я не можу точно сказати, що це таке). Це, мабуть, якесь розширення Bitmap, оскільки Canvas надає лише конструктори для Bitmap та GL.
sksamuel

Чудова допомога, дякую! Про відповідь 2. У своєму запитанні я мав на увазі стандартні перегляди, а не SurfaceViews. Припустимо, у мене є відносний макет із великою кількістю полів та кнопок. У цьому випадку Чи поверхня приєднана до всього вікна та поділяється всіма переглядами в ієрархії перегляду?
фьодорананьєв

1
Пам'ятайте, що поверхня - це лише набір пікселів. Таким чином, кожен вид поверхні має свою поверхню, і кожен може бути відображений на іншій частині екрана. Їм не потрібно заповнювати екран (хоча це звичайне використання для візуалізації графіки в повноекранній грі).
sksamuel

1
Я дійсно не вважав би растрові зображення та поверхню рівноцінними. Поверхня - це предмет, про який знає поверхневий флангер, композитор вікон. Тобто це щось, що прямо видно на екрані, має Z-порядок на екрані тощо
hackbod
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.