ציור על אובייקטים בלוח הציור

ה-codelab הזה הוא חלק מהקורס Advanced Android in Kotlin (פיתוח מתקדם ל-Android ב-Kotlin). כדי להפיק את המרב מהקורס הזה, מומלץ לעבוד על ה-codelabs לפי הסדר, אבל זה לא חובה. כל ה-codelab של הקורס מפורטים בדף הנחיתה של ה-codelab בנושא Android מתקדם ב-Kotlin.

מבוא

ב-Android, יש כמה טכניקות להטמעה של גרפיקה דו-ממדית ואנימציות בהתאמה אישית בתצוגות.

בנוסף לשימוש ב-drawables, אפשר ליצור שרטוטים דו-ממדיים באמצעות שיטות השרטוט של המחלקה Canvas. ‫Canvas הוא משטח ציור דו-ממדי שמספק שיטות לציור. האפשרות הזו שימושית אם האפליקציה צריכה לצייר את עצמה מחדש באופן קבוע, כי מה שהמשתמש רואה משתנה לאורך זמן. ב-codelab הזה תלמדו איך ליצור ולצייר על בד ציור שמוצג ב-View.

סוגי הפעולות שאפשר לבצע באזור העריכה כוללים:

  • ממלאים את כל האזור המשותף בצבע.
  • ציור צורות, כמו מלבנים, קשתות ונתיבים, שמעוצבות כמוגדר באובייקט Paint. אובייקט Paint מכיל את פרטי הסגנון והצבע של אופן הציור של צורות גיאומטריות (כמו קו, מלבן, אליפסה ונתיבים), או למשל, את הגופן של הטקסט.
  • להחיל טרנספורמציות, כמו תרגום, שינוי קנה מידה או טרנספורמציות מותאמות אישית.
  • חיתוך, כלומר החלת צורה או נתיב על אזור העריכה כדי להגדיר את החלקים הגלויים שלו.

איך אפשר לחשוב על ציור ב-Android (פשוט מאוד!)

ציור ב-Android או בכל מערכת מודרנית אחרת הוא תהליך מורכב שכולל שכבות של הפשטות ואופטימיזציות עד לרמת החומרה. האופן שבו Android מצייר הוא נושא מרתק שנכתב עליו הרבה, והפרטים שלו לא נכללים ב-codelab הזה.

במסגרת ה-codelab הזה, ובאפליקציה שלו שמציירת על בד כדי להציג במסך מלא, אפשר לחשוב על זה כך.

  1. צריך תצוגה כדי להציג את מה שמציירים. יכול להיות שזו אחת מהתצוגות שמסופקות על ידי מערכת Android. לחלופין, ב-Codelab הזה, יוצרים תצוגה בהתאמה אישית שמשמשת כתצוגת התוכן של האפליקציה (MyCanvasView).
  2. לתצוגה הזו, כמו לכל התצוגות, יש אזור עריכה משלה (canvas).
  3. הדרך הכי בסיסית לשרטוט על הקנבס של תצוגה היא להחליף את השיטה onDraw() ולשרטט על הקנבס שלה.
  4. כשיוצרים ציור, צריך לשמור במטמון את מה שציירתם קודם. יש כמה דרכים לשמור את הנתונים במטמון, אחת מהן היא במפת סיביות (extraBitmap). דרך נוספת היא לשמור היסטוריה של מה שציירתם כקואורדינטות והוראות.
  5. כדי לצייר על מפת הסיביות של הזיכרון (extraBitmap) באמצעות API לציור על בד ציור, יוצרים בד ציור לזיכרון (extraCanvas) עבור מפת הסיביות של הזיכרון.
  6. אחר כך מציירים על אזור הציור של המטמון (extraCanvas), והציור מועבר למפת הסיביות של המטמון (extraBitmap).
  7. כדי להציג את כל מה שמצויר על המסך, צריך להורות לאזור העריכה של התצוגה (canvas) לצייר את מפת הסיביות של השמירה במטמון (extraBitmap).

מה שכדאי לדעת

  • איך ליצור אפליקציה עם פעילות, פריסה בסיסית ולהפעיל אותה באמצעות Android Studio.
  • איך משייכים מטפלי אירועים לתצוגות.
  • איך יוצרים תצוגה בהתאמה אישית

מה תלמדו

  • איך ליצור Canvas ולצייר עליו בתגובה למגע של המשתמש.

הפעולות שתבצעו:

  • ליצור אפליקציה שמציירת קווים על המסך בתגובה למגע של המשתמש במסך.
  • ללכוד אירועי תנועה, ובתגובה, לצייר קווים על בד ציור שמוצג בתצוגה מותאמת אישית במסך מלא.

האפליקציה MiniPaint משתמשת בתצוגה מותאמת אישית כדי להציג קו בתגובה למגע של המשתמש, כמו שמוצג בצילום המסך שלמטה.

שלב 1. יצירת פרויקט MiniPaint

  1. יוצרים פרויקט חדש ב-Kotlin בשם MiniPaint באמצעות התבנית Empty Activity.
  2. פותחים את הקובץ app/res/values/colors.xml ומוסיפים את שני הצבעים הבאים.
<color name="colorBackground">#FFFF5500</color>
<color name="colorPaint">#FFFFEB3B</color>
  1. פתיחה של styles.xml
  2. בסגנון האב של AppTheme, מחליפים את DarkActionBar ב-NoActionBar. הפעולה הזו מסירה את סרגל הפעולות, כדי שתוכלו לצייר במסך מלא.
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

שלב 2. יצירת המחלקה MyCanvasView

בשלב הזה יוצרים תצוגה בהתאמה אישית, MyCanvasView, לציור.

  1. בחבילה app/java/com.example.android.minipaint, יוצרים New > Kotlin File/Class בשם MyCanvasView.
  2. מגדירים את המחלקה MyCanvasView כך שתהיה מחלקה נגזרת של המחלקה View ומעבירים את context: Context. מאשרים את הייבוא המוצע.
import android.content.Context
import android.view.View

class MyCanvasView(context: Context) : View(context) {
}

שלב 3. הגדרת MyCanvasView כתצוגת התוכן

כדי להציג את מה שתציירו ב-MyCanvasView, צריך להגדיר אותו כתצוגת התוכן של MainActivity.

  1. פותחים את strings.xml ומגדירים מחרוזת לשימוש בתיאור התוכן של התצוגה.
<string name="canvasContentDescription">Mini Paint is a simple line drawing app.
   Drag your fingers to draw. Rotate the phone to clear.</string>
  1. פתיחה של MainActivity.kt
  2. ב-onCreate(), מוחקים את setContentView(R.layout.activity_main).
  3. ליצור מופע של MyCanvasView.
val myCanvasView = MyCanvasView(this)
  1. מתחת לזה, מבקשים מסך מלא עבור הפריסה של myCanvasView. כדי לעשות את זה, מגדירים את הדגל SYSTEM_UI_FLAG_FULLSCREEN לערך myCanvasView. כך התצוגה ממלאת את המסך באופן מלא.
myCanvasView.systemUiVisibility = SYSTEM_UI_FLAG_FULLSCREEN
  1. מוסיפים תיאור של התוכן.
myCanvasView.contentDescription = getString(R.string.canvasContentDescription)
  1. מתחת לזה, מגדירים את התצוגה של התוכן ל-myCanvasView.
setContentView(myCanvasView)
  1. מריצים את האפליקציה. יוצג מסך לבן לגמרי, כי אין גודל לקנבס ולא ציירתם בו כלום עדיין.

שלב 1. החלפת ברירת המחדל של onSizeChanged()

המערכת של Android קוראת לשיטה onSizeChanged() בכל פעם שגודל התצוגה משתנה. מכיוון שהתצוגה מתחילה ללא גודל, השיטה onSizeChanged() של התצוגה נקראת גם אחרי שהפעילות יוצרת אותה ומנפחת אותה. לכן, השיטה onSizeChanged() היא המקום האידיאלי ליצור ולהגדיר את הקנבס של התצוגה.

  1. ב-MyCanvasView, ברמת המחלקה, מגדירים משתנים לקנבס ולמפת סיביות. להתקשר אל extraCanvas ואל extraBitmap. אלה הם מפת הסיביות והקנבס שלכם לצורך שמירת מה ששורטט בעבר במטמון.
private lateinit var extraCanvas: Canvas
private lateinit var extraBitmap: Bitmap
  1. מגדירים משתנה ברמת המחלקה backgroundColor לצבע הרקע של אזור הציור ומאתחלים אותו ל-colorBackground שהגדרתם קודם.
private val backgroundColor = ResourcesCompat.getColor(resources, R.color.colorBackground, null)
  1. ב-MyCanvasView, משנים את ברירת המחדל של אמצעי התשלום onSizeChanged(). המערכת של Android קוראת לשיטת הקריאה החוזרת הזו עם המידות המשתנות של המסך, כלומר עם רוחב וגובה חדשים (לשינוי) ורוחב וגובה ישנים (לשינוי מ).
override fun onSizeChanged(width: Int, height: Int, oldWidth: Int, oldHeight: Int) {
   super.onSizeChanged(width, height, oldWidth, oldHeight)
}
  1. בתוך onSizeChanged(), יוצרים מופע של Bitmap עם הרוחב והגובה החדשים, שהם גודל המסך, ומקצים אותו ל-extraBitmap. הארגומנט השלישי הוא הגדרת הצבע של מפת הסיביות. ARGB_8888 מאחסן כל צבע ב-4 בייטים ומומלץ לשימוש.
extraBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
  1. יוצרים מכונת Canvas מ-extraBitmap ומקצים אותה ל-extraCanvas.
 extraCanvas = Canvas(extraBitmap)
  1. מציינים את צבע הרקע שבו רוצים למלא את extraCanvas.
extraCanvas.drawColor(backgroundColor)
  1. אם בוחנים את onSizeChanged(), רואים שנוצרים מפת סיביות וקנבס חדשים בכל פעם שהפונקציה מופעלת. צריך ליצור מפת סיביות חדשה כי הגודל השתנה. עם זאת, מדובר בדליפת זיכרון, והמפות הביטמפיות הישנות נשארות. כדי לפתור את הבעיה, צריך למחזר את extraBitmap לפני שיוצרים את הבא, על ידי הוספת הקוד הזה מיד אחרי הקריאה אל super.
if (::extraBitmap.isInitialized) extraBitmap.recycle()

שלב 2. החלפת השיטה onDraw()

כל העבודה על הציור של MyCanvasView מתבצעת ב-onDraw().

כדי להתחיל, מציגים את הקנבס וממלאים את המסך בצבע הרקע שהגדרתם בonSizeChanged().

  1. מחליף את onDraw() ומצייר את התוכן של extraBitmap שנשמר במטמון בקנבס שמשויך לתצוגה. יש כמה גרסאות של שיטת drawBitmap() Canvas. בקוד הזה, מציינים את מפת הסיביות, את קואורדינטות ה-x וה-y (בפיקסלים) של הפינה הימנית העליונה, ואת null בשביל Paint, כי תגדירו את זה בהמשך.
override fun onDraw(canvas: Canvas) {
   super.onDraw(canvas)
canvas.drawBitmap(extraBitmap, 0f, 0f, null)
}


שימו לב שהקנבס שמועבר אל onDraw() ומשמש את המערכת להצגת מפת הביטים שונה מהקנבס שיצרתם בשיטה onSizeChanged() ושהשתמשתם בו כדי לצייר על מפת הביטים.

  1. מריצים את האפליקציה. כל המסך אמור להיות מלא בצבע הרקע שצוין.

כדי לצייר, צריך אובייקט Paint שמציין איך הדברים מעוצבים כשהם מצוירים, ואובייקט Path שמציין מה מצויר.

שלב 1. הפעלת אובייקט Paint

  1. ב-MyCanvasView.kt, ברמה העליונה של הקובץ, מגדירים קבוע לרוחב הקו.
private const val STROKE_WIDTH = 12f // has to be float
  1. ברמת המחלקה של MyCanvasView, מגדירים משתנה drawColor להחזקת הצבע שבו רוצים לצייר, ומאתחלים אותו באמצעות המשאב colorPaint שהגדרתם קודם.
private val drawColor = ResourcesCompat.getColor(resources, R.color.colorPaint, null)
  1. ברמת המחלקה, מוסיפים משתנה paint לאובייקט Paint ומאתחלים אותו באופן הבא.
// Set up the paint with which to draw.
private val paint = Paint().apply {
   color = drawColor
   // Smooths out edges of what is drawn without affecting shape.
   isAntiAlias = true
   // Dithering affects how colors with higher-precision than the device are down-sampled.
   isDither = true
   style = Paint.Style.STROKE // default: FILL
   strokeJoin = Paint.Join.ROUND // default: MITER
   strokeCap = Paint.Cap.ROUND // default: BUTT
   strokeWidth = STROKE_WIDTH // default: Hairline-width (really thin)
}
  • ה-color של paint הוא drawColor שהגדרתם קודם.
  • isAntiAlias מגדיר אם להחיל החלקת קצוות. הגדרה של isAntiAlias ל-true מחליקה את הקצוות של מה שמצויר בלי להשפיע על הצורה.
  • isDither, כש-true, משפיע על האופן שבו צבעים עם דיוק גבוה יותר מהמכשיר עוברים דגימת חסר. לדוגמה, דית'רינג היא השיטה הנפוצה ביותר לצמצום טווח הצבעים של תמונות ל-256 צבעים (או פחות).
  • style מגדיר את סוג הצביעה שתיעשה לקו, שהוא בעצם קו. ‫Paint.Style מציין אם הפרימיטיב שמציירים מלא, מתוחם או שניהם (באותו צבע). כברירת מחדל, הצבע ממלא את האובייקט שאליו הוא מוחל. (האפשרות Fill צובעת את החלק הפנימי של הצורה, ואילו האפשרות Stroke צובעת את המתאר שלה).
  • strokeJoin of Paint.Join מציין איך קווים וקטעי עקומה מתחברים בנתיב עם קו מתאר. ערך ברירת המחדל הוא MITER.
  • strokeCap מגדיר את הצורה של קצה הקו כפקק. ‫Paint.Cap מציין את ההתחלה והסיום של קווים ונתיבים עם קו מתאר. ערך ברירת המחדל הוא BUTT.
  • strokeWidth מציין את רוחב הקו בפיקסלים. ברירת המחדל היא רוחב דק מאוד, ולכן היא מוגדרת לקבוע STROKE_WIDTH שהגדרתם קודם.

שלב 2. אתחול אובייקט Path

Path הוא הנתיב של מה שהמשתמש מצייר.

  1. ב-MyCanvasView, מוסיפים משתנה path ומאתחלים אותו באמצעות אובייקט Path כדי לאחסן את הנתיב שמצויר כשעוקבים אחרי המגע של המשתמש במסך. ייבוא של android.graphics.Path עבור Path.
private var path = Path()

שלב 1. תגובה לתנועה במסך

השיטה onTouchEvent() בתצוגה נקראת בכל פעם שהמשתמש נוגע במסך.

  1. ב-MyCanvasView, מחליפים את השיטה onTouchEvent() כדי לשמור במטמון את הקואורדינטות x ו-y של event שהועבר. לאחר מכן משתמשים בwhen expression כדי לטפל באירועי תנועה של נגיעה במסך, תנועה במסך ושחרור הנגיעה במסך. אלה האירועים שמעניינים אותנו כדי לשרטט קו על המסך. לכל סוג אירוע, קוראים לשיטת כלי עזר, כמו שמוצג בקוד שלמטה. רשימה מלאה של אירועי מגע מופיעה במסמכי התיעוד של המחלקה MotionEvent.
override fun onTouchEvent(event: MotionEvent): Boolean {
   motionTouchEventX = event.x
   motionTouchEventY = event.y

   when (event.action) {
       MotionEvent.ACTION_DOWN -> touchStart()
       MotionEvent.ACTION_MOVE -> touchMove()
       MotionEvent.ACTION_UP -> touchUp()
   }
   return true
}
  1. ברמת המחלקה, מוסיפים את המשתנים החסרים motionTouchEventX ו-motionTouchEventY כדי לשמור במטמון את הקואורדינטות x ו-y של אירוע המגע הנוכחי (הקואורדינטות MotionEvent). מאתחלים אותם ל-0f.
private var motionTouchEventX = 0f
private var motionTouchEventY = 0f
  1. יוצרים stubs לשלוש הפונקציות touchStart(), touchMove() ו-touchUp().
private fun touchStart() {}

private fun touchMove() {}

private fun touchUp() {}
  1. הקוד אמור להיבנות ולרוץ, אבל עדיין לא תראו שום דבר שונה מהרקע הצבעוני.

שלב 2. הטמעה של touchStart()‎

המערכת קוראת לשיטה הזו כשהמשתמש נוגע במסך בפעם הראשונה.

  1. ברמת המחלקה, מוסיפים משתנים כדי לשמור במטמון את הערכים האחרונים של x ו-y. אחרי שהמשתמש מפסיק לזוז ומסיר את האצבע מהמסך, זו נקודת ההתחלה של הנתיב הבא (הקטע הבא של הקו לציור).
private var currentX = 0f
private var currentY = 0f
  1. מטמיעים את ה-method‏ touchStart() באופן הבא. מאפסים את path, עוברים לקואורדינטות x-y של אירוע המגע (motionTouchEventX ו-motionTouchEventY), ומקצים את currentX ו-currentY לערך הזה.
private fun touchStart() {
   path.reset()
   path.moveTo(motionTouchEventX, motionTouchEventY)
   currentX = motionTouchEventX
   currentY = motionTouchEventY
}

שלב 3. הטמעה של touchMove()

  1. ברמת הכיתה, מוסיפים משתנה touchTolerance ומגדירים אותו לערך ViewConfiguration.get(context).scaledTouchSlop.
private val touchTolerance = ViewConfiguration.get(context).scaledTouchSlop

כשמשתמשים בנתיב, אין צורך לצייר כל פיקסל ולבקש רענון של התצוגה בכל פעם. במקום זאת, אפשר (וכדאי) לבצע אינטרפולציה של נתיב בין נקודות כדי לשפר את הביצועים.

  • אם האצבע כמעט לא זזה, אין צורך לצייר.
  • אם האצבע זזה פחות מהמרחק touchTolerance, לא מציירים.
  • scaledTouchSlop מחזירה את המרחק בפיקסלים שהמגע יכול לנוע לפני שהמערכת חושבת שהמשתמש גולל.
  1. מגדירים את השיטה touchMove(). חישוב המרחק שעבר (dx, dy), יצירת עקומה בין שתי הנקודות ואחסון שלה ב-path, עדכון הסיכום המצטבר של currentX ו-currentY ושרטוט של path. לאחר מכן מתקשרים למספר invalidate() כדי לאלץ את ציור המסך מחדש עם path המעודכן.
private fun touchMove() {
   val dx = Math.abs(motionTouchEventX - currentX)
   val dy = Math.abs(motionTouchEventY - currentY)
   if (dx >= touchTolerance || dy >= touchTolerance) {
       // QuadTo() adds a quadratic bezier from the last point,
       // approaching control point (x1,y1), and ending at (x2,y2).
       path.quadTo(currentX, currentY, (motionTouchEventX + currentX) / 2, (motionTouchEventY + currentY) / 2)
       currentX = motionTouchEventX
       currentY = motionTouchEventY
       // Draw the path in the extra bitmap to cache it.
       extraCanvas.drawPath(path, paint)
   }
   invalidate()
}

הסבר מפורט יותר על השיטה הזו:

  1. חשבו את המרחק שהוזז (dx, dy).
  2. אם התנועה הייתה גדולה יותר מהסבילות למגע, מוסיפים פלח לנתיב.
  3. מגדירים את נקודת ההתחלה של המקטע הבא כנקודת הסיום של המקטע הנוכחי.
  4. שימוש ב-quadTo() במקום ב-lineTo() יוצר קו חלק ללא פינות. ראו עקומות בזייה.
  5. מתקשרים אל invalidate() (בסופו של דבר מתקשרים אל onDraw()) ומציירים מחדש את התצוגה.

שלב 4: הטמעה של touchUp()

כשהמשתמש מרים את האצבע מהמסך, צריך רק לאפס את הנתיב כדי שלא ייצג שוב. לא מצויר כלום, ולכן לא צריך לבטל את התוקף.

  1. מטמיעים את ה-method‏ touchUp().
private fun touchUp() {
   // Reset the path so it doesn't get drawn again.
   path.reset()
}
  1. מריצים את הקוד ומשרטטים על המסך עם האצבע. שימו לב: אם מסובבים את המכשיר, המסך מתנקה כי מצב הציור לא נשמר. באפליקציה לדוגמה הזו, זה נעשה בכוונה כדי לתת למשתמש דרך פשוטה לנקות את המסך.

שלב 5: מציירים מסגרת סביב הסקיצה

בזמן שהמשתמש מצייר על המסך, האפליקציה יוצרת את הנתיב ושומרת אותו במפת הביטים extraBitmap. השיטה onDraw() מציגה את מפת הסיביות הנוספת בקנבס של התצוגה. אפשר לצייר עוד ב-onDraw(). לדוגמה, אפשר לצייר צורות אחרי שמציירים את מפת הביטים.

בשלב הזה מציירים מסגרת מסביב לקצה של התמונה.

  1. ב-MyCanvasView, מוסיפים משתנה בשם frame שמכיל אובייקט Rect.
private lateinit var frame: Rect
  1. בסוף onSizeChanged() מגדירים שוליים פנימיים ומוסיפים קוד ליצירת Rect שישמש למסגרת, באמצעות המידות החדשות והשוליים הפנימיים.
// Calculate a rectangular frame around the picture.
val inset = 40
frame = Rect(inset, inset, width - inset, height - inset)
  1. ב-onDraw(), אחרי שמציירים את מפת הסיביות, מציירים מלבן.
// Draw a frame around the canvas.
canvas.drawRect(frame, paint)
  1. מריצים את האפליקציה. שימו לב למסגרת.

משימה (אופציונלית): אחסון נתונים בנתיב

באפליקציה הנוכחית, פרטי הציור מאוחסנים במפת סיביות. זה פתרון טוב, אבל יש עוד דרכים לאחסן את נתוני הציור. אופן האחסון של היסטוריית הציורים תלוי באפליקציה ובדרישות השונות שלכם. לדוגמה, אם מציירים צורות, אפשר לשמור רשימה של צורות עם המיקום והמידות שלהן. באפליקציית MiniPaint, אפשר לשמור את הנתיב כקובץ Path. אם רוצים לנסות, הנה תיאור כללי של התהליך.

  1. ב-MyCanvasView, מסירים את כל הקוד של extraCanvas ושל extraBitmap.
  2. מוסיפים משתנים לנתיב עד עכשיו ולנתיב שמציירים כרגע.
// Path representing the drawing so far
private val drawing = Path()

// Path representing what's currently being drawn
private val curPath = Path()
  1. ב-onDraw(), במקום לצייר את מפת הביטים, מציירים את הנתיבים המאוחסנים והנוכחיים.
// Draw the drawing so far
canvas.drawPath(drawing, paint)
// Draw any current squiggle
canvas.drawPath(curPath, paint)
// Draw a frame around the canvas
canvas.drawRect(frame, paint)
  1. ב-touchUp(), מוסיפים את הנתיב הנוכחי לנתיב הקודם ומאפסים את הנתיב הנוכחי.
// Add the current path to the drawing so far
drawing.addPath(curPath)
// Rewind the current path for the next touch
curPath.reset()
  1. מריצים את האפליקציה, ולא אמור להיות שום הבדל.

מורידים את הקוד של ה-Codelab המוגמר.

$  git clone https://github.com/googlecodelabs/android-kotlin-drawing-canvas


אפשר גם להוריד את המאגר כקובץ ZIP, לבטל את הדחיסה שלו ולפתוח אותו ב-Android Studio.

הורדת קובץ Zip

  • Canvas הוא משטח ציור דו-ממדי שמספק שיטות לציור.
  • אפשר לשייך את Canvas למופע של View שבו הוא מוצג.
  • אובייקט Paint מכיל את פרטי הסגנון והצבע של אופן הציור של צורות גיאומטריות (כמו קו, מלבן, אליפסה ונתיבים) וטקסט.
  • דפוס נפוץ לעבודה עם אזור ציור הוא ליצור תצוגה בהתאמה אישית ולבטל את השיטות onDraw() ו-onSizeChanged().
  • אפשר לבטל את השיטה onTouchEvent() כדי לתעד את המגע של המשתמשים ולהגיב להם על ידי ציור דברים.
  • אפשר להשתמש במפת סיביות נוספת כדי לשמור במטמון מידע לגבי ציורים שמשתנים לאורך זמן. אפשר גם לאחסן צורות או נתיב.

קורס ב-Udacity:

מסמכי תיעוד למפתחי Android:

בקטע הזה מפורטות אפשרויות למשימות ביתיות לתלמידים שעובדים על ה-Codelab הזה כחלק מקורס בהנחיית מדריך. המורה צריך:

  • אם צריך, מקצים שיעורי בית.
  • להסביר לתלמידים איך להגיש מטלות.
  • בודקים את שיעורי הבית.

אנשי ההוראה יכולים להשתמש בהצעות האלה כמה שרוצים, ומומלץ להם להקצות כל שיעורי בית אחרים שהם חושבים שמתאימים.

אם אתם עובדים על ה-codelab הזה לבד, אתם יכולים להשתמש במשימות האלה כדי לבדוק את הידע שלכם.

עונים על השאלות הבאות

שאלה 1

אילו מהרכיבים הבאים נדרשים כדי לעבוד עם Canvas? יש לבחור בכל האפשרויות הרלוונטיות.

Bitmap

Paint

Path

View

שאלה 2

מה קורה כשמתקשרים אל invalidate() (באופן כללי)?

‫▢ מבטל את התוקף של האפליקציה ומפעיל אותה מחדש.

‫▢ מחיקת השרטוט ממפת הביטים.

‫▢ מציין שלא צריך להריץ את הקוד הקודם.

‫▢ אומר למערכת שהיא צריכה לצייר מחדש את המסך.

שאלה 3

מה התפקיד של האובייקטים Canvas,‏ Bitmap ו-Paint?

‫▢ משטח ציור דו-ממדי, מפת סיביות שמוצגת על המסך, מידע על סגנון הציור.

‫▢ משטח לציור תלת-ממדי, מפת סיביות לאחסון במטמון של הנתיב, מידע על סגנון הציור.

‫▢ משטח לציור דו-ממדי, מפת סיביות שמוצגת במסך, סגנון לתצוגה.

‫▢ מטמון לציור מידע, מפת סיביות לציור, מידע על סגנון לציור.

קישורים למדריכי Codelab נוספים בקורס הזה זמינים בדף הנחיתה של מדריכי Codelab בנושא Android מתקדם ב-Kotlin.