طراحی روی اشیاء بوم

این کد لبه بخشی از دوره Advanced Android in Kotlin است. اگر از طریق کدها به ترتیب کار کنید، بیشترین ارزش را از این دوره خواهید گرفت، اما اجباری نیست. همه کدهای دوره در صفحه فرود Android Advanced in Kotlin Codelabs فهرست شده اند.

مقدمه

در اندروید، چندین تکنیک برای پیاده سازی گرافیک ها و انیمیشن های دو بعدی سفارشی در نماها در دسترس دارید.

علاوه بر استفاده از drawable ها ، می توانید با استفاده از روش های ترسیم کلاس Canvas ، نقاشی های دو بعدی ایجاد کنید. Canvas یک سطح طراحی دو بعدی است که روش هایی را برای طراحی ارائه می دهد. این زمانی مفید است که برنامه شما نیاز به ترسیم منظم خود داشته باشد، زیرا آنچه کاربر می بیند در طول زمان تغییر می کند. در این کد لبه، نحوه ایجاد و طراحی روی بوم که در یک View نمایش داده می شود را یاد می گیرید.

انواع عملیاتی که می توانید بر روی بوم انجام دهید عبارتند از:

  • کل بوم را با رنگ پر کنید.
  • شکل هایی مانند مستطیل ها، کمان ها و مسیرهایی را که در یک شیء Paint استایل بندی شده اند، رسم کنید. شی Paint اطلاعات سبک و رنگ را در مورد نحوه ترسیم هندسه ها (مانند خط، مستطیل، بیضی، و مسیرها) یا به عنوان مثال، نوع نوشتار نگه می دارد.
  • تغییراتی مانند ترجمه، مقیاس‌بندی یا تبدیل‌های سفارشی را اعمال کنید.
  • گیره، یعنی یک شکل یا مسیر را روی بوم اعمال کنید تا قسمت های قابل مشاهده آن را مشخص کنید.

چگونه می توانید به طراحی اندروید فکر کنید (فوق العاده ساده!)

ترسیم در اندروید یا هر سیستم مدرن دیگری، فرآیند پیچیده ای است که شامل لایه هایی از انتزاعات و بهینه سازی ها تا سخت افزار است. نحوه ترسیم اندروید موضوع جذابی است که درباره آن مطالب زیادی نوشته شده است و جزئیات آن خارج از حوصله این کدهاست.

در زمینه این کد لبه، و برنامه آن که روی بوم برای نمایش در نمای تمام صفحه ترسیم می کند، می توانید به روش زیر به آن فکر کنید.

  1. برای نمایش آنچه می‌کشید به یک نمای نیاز دارید. این می تواند یکی از نماهای ارائه شده توسط سیستم اندروید باشد. یا، در این لبه کد، یک نمای سفارشی ایجاد می کنید که به عنوان نمای محتوا برای برنامه شما عمل می کند ( MyCanvasView ).
  2. این نما، مانند همه نماها، با بوم خاص خود ( canvas ) همراه است.
  3. برای ابتدایی‌ترین روش طراحی روی بوم یک view، متد onDraw() آن را نادیده می‌گیرید و روی بوم آن ترسیم می‌کنید.
  4. هنگام ساختن نقشه، باید آنچه را که قبلاً ترسیم کرده اید، کش کنید. روش‌های مختلفی برای ذخیره‌سازی داده‌های شما وجود دارد، یکی در بیت مپ ( extraBitmap ). دیگری ذخیره تاریخچه ای از آنچه ترسیم کرده اید به عنوان مختصات و دستورالعمل هاست.
  5. برای ترسیم به بیت مپ ذخیره خود ( extraBitmap ) با استفاده از بوم طراحی API، یک بوم کش ( extraCanvas ) برای بیت مپ ذخیره خود ایجاد می کنید.
  6. سپس روی بوم ذخیره خود ( extraCanvas )، که روی بیت مپ ذخیره شما ( extraBitmap ) کشیده می شود، ترسیم می کنید.
  7. برای نمایش هر چیزی که روی صفحه کشیده شده است، به بوم نمایش ( canvas ) می‌گویید که بیت مپ ذخیره‌سازی شده ( extraBitmap ) را بکشد.

آنچه از قبل باید بدانید

  • نحوه ایجاد یک برنامه با Activity، یک طرح اولیه و اجرای آن با استفاده از 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 را باز کنید و یک رشته برای استفاده در توضیحات محتوای view تعریف کنید.
<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() را لغو کنید

متد onSizeChanged() توسط سیستم اندروید هر زمان که یک view تغییر اندازه می‌دهد فراخوانی می‌شود. از آنجایی که view بدون اندازه شروع می شود، متد onSizeChanged() view نیز پس از اینکه Activity برای اولین بار آن را ایجاد کرد و آن را باد کرد فراخوانی می شود. بنابراین، این متد 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() لغو کنید. این روش بازخوانی توسط سیستم اندروید با ابعاد صفحه تغییر یافته، یعنی با عرض و ارتفاع جدید (برای تغییر به) و عرض و ارتفاع قدیمی (برای تغییر از) فراخوانی می شود.
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 کش شده را روی بوم مرتبط با view بکشید. متد drawBitmap() Canvas در چندین نسخه موجود است. در این کد، بیت مپ، مختصات x و y (بر حسب پیکسل) گوشه سمت چپ بالا و null برای Paint ارائه می‌کنید، همانطور که بعداً آن را تنظیم خواهید کرد.
override fun onDraw(canvas: Canvas) {
   super.onDraw(canvas)
canvas.drawBitmap(extraBitmap, 0f, 0f, null)
}


توجه داشته باشید که بوم ارسال شده به onDraw() و توسط سیستم برای نمایش bitmap با آنچه که در متد onSizeChanged() ایجاد کرده اید و برای ترسیم روی bitmap استفاده کرده اید متفاوت است.

  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 مشخص می‌کند که آیا طرح اولیه ترسیم شده پر، نوازش شده یا هر دو (به یک رنگ) باشد. پیش فرض این است که شیئی را که رنگ روی آن اعمال می شود پر کنید. («پر» داخل شکل را رنگ می کند، در حالی که «سکته مغزی» از طرح کلی آن پیروی می کند.)
  • strokeJoin از Paint.Join نحوه اتصال خطوط و بخش های منحنی را در یک مسیر stroked مشخص می کند. پیش فرض MITER است.
  • strokeCap شکل انتهای خط را به صورت کلاهک تنظیم می کند. Paint.Cap نحوه شروع و پایان خطوط و مسیرهای stroked را مشخص می کند. پیش فرض BUTT است.
  • strokeWidth عرض stroke را بر حسب پیکسل مشخص می کند. پیش‌فرض عرض خط مو است که واقعاً نازک است، بنابراین روی ثابت STROKE_WIDTH که قبلاً تعریف کردید تنظیم می‌شود.

مرحله 2. یک شی Path را راه اندازی کنید

Path مسیر چیزی است که کاربر ترسیم می کند.

  1. در MyCanvasView ، یک path متغیر اضافه کنید و آن را با یک شی Path مقداردهی اولیه کنید تا مسیری که هنگام دنبال کردن لمس کاربر روی صفحه ترسیم می‌شود، ذخیره شود. android.graphics.Path for the Path را وارد کنید.
private var path = Path()

مرحله 1. به حرکت روی نمایشگر پاسخ دهید

متد onTouchEvent() در یک view هر زمان که کاربر صفحه نمایش را لمس کند فراخوانی می شود.

  1. در MyCanvasView ، روش onTouchEvent() را لغو کنید تا مختصات x و y event ارسال شده را ذخیره کنید. سپس از عبارت when برای مدیریت رویدادهای حرکتی برای لمس کردن روی صفحه، حرکت روی صفحه و رها کردن لمس روی صفحه استفاده کنید. اینها رویدادهای مورد علاقه برای کشیدن یک خط روی صفحه هستند. برای هر نوع رویداد، همانطور که در کد زیر نشان داده شده است، یک متد ابزاری را فراخوانی کنید. برای لیست کامل رویدادهای لمسی، به مستندات کلاس 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. برای سه تابع 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. متد touchStart() را به صورت زیر پیاده سازی کنید. path را بازنشانی کنید، به مختصات xy رویداد لمسی بروید ( 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() یک خط صاف و بدون گوشه ایجاد می کند. منحنی های Bezier را ببینید.
  5. invalidate() را فراخوانی کنید (در نهایت onDraw() فراخوانی کنید و view را دوباره ترسیم کنید.

مرحله 4: پیاده سازی touchUp()

هنگامی که کاربر لمس خود را بلند می کند، تنها چیزی که لازم است این است که مسیر را بازنشانی کند تا دوباره ترسیم نشود. هیچ چیزی ترسیم نشده است، بنابراین نیازی به ابطال نیست.

  1. متد touchUp() پیاده سازی کنید.
private fun touchUp() {
   // Reset the path so it doesn't get drawn again.
   path.reset()
}
  1. کد خود را اجرا کنید و از انگشت خود برای کشیدن روی صفحه استفاده کنید. توجه داشته باشید که اگر دستگاه را بچرخانید، صفحه نمایش پاک می شود، زیرا حالت ترسیم ذخیره نمی شود. برای این برنامه نمونه، این طراحی شده است تا به کاربر یک راه ساده برای پاک کردن صفحه نمایش بدهد.

مرحله 5: یک قاب در اطراف طرح بکشید

همانطور که کاربر روی صفحه طراحی می کند، برنامه شما مسیر را می سازد و آن را در bitmap extraBitmap ذخیره می کند. متد onDraw() بیت مپ اضافی را در بوم view نمایش می دهد. می توانید در onDraw() طراحی بیشتری انجام دهید. به عنوان مثال، می توانید پس از ترسیم بیت مپ، شکل ها را ترسیم کنید.

در این مرحله شما یک قاب دور لبه تصویر میکشید.

  1. در MyCanvasView ، متغیری به نام frame اضافه کنید که یک شی Rect در خود جای دهد.
private lateinit var frame: Rect
  1. در انتهای onSizeChanged() یک inset تعریف کنید و کدی را برای ایجاد Rect که برای فریم استفاده می شود، با استفاده از ابعاد جدید و inset اضافه کنید.
// 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. برنامه خود را اجرا کنید، و بله، هیچ تفاوتی نباید وجود داشته باشد.

دانلود کد برای کد لبه تمام شده..

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


یا می‌توانید مخزن را به‌عنوان یک فایل Zip دانلود کنید، آن را از حالت فشرده خارج کنید و در Android Studio باز کنید.

زیپ را دانلود کنید

  • Canvas یک سطح طراحی 2 بعدی است که روش هایی را برای طراحی ارائه می دهد.
  • Canvas می توان با یک نمونه View که آن را نمایش می دهد مرتبط کرد.
  • شی Paint اطلاعات سبک و رنگ را در مورد نحوه ترسیم هندسه (مانند خط، مستطیل، بیضی و مسیرها) و متن نگه می دارد.
  • یک الگوی رایج برای کار با یک بوم، ایجاد یک نمای سفارشی و نادیده گرفتن متدهای onDraw() و onSizeChanged() است.
  • روش onTouchEvent() را نادیده بگیرید تا لمس کاربر را ثبت کنید و با ترسیم چیزها به آنها پاسخ دهید.
  • می توانید از یک بیت مپ اضافی برای ذخیره اطلاعات نقشه هایی که در طول زمان تغییر می کنند استفاده کنید. از طرف دیگر، می توانید اشکال یا یک مسیر را ذخیره کنید.

دوره بی ادبی:

مستندات توسعه دهنده اندروید:

این بخش، تکالیف احتمالی را برای دانش‌آموزانی که در این آزمایشگاه کد به عنوان بخشی از دوره‌ای که توسط یک مربی هدایت می‌شود، کار می‌کنند، فهرست می‌کند. این وظیفه مربی است که موارد زیر را انجام دهد:

  • در صورت نیاز تکالیف را تعیین کنید.
  • نحوه ارسال تکالیف را با دانش آموزان در میان بگذارید.
  • تکالیف را نمره دهید.

مربیان می‌توانند از این پیشنهادات به اندازه‌ای که می‌خواهند استفاده کنند، و باید با خیال راحت هر تکلیف دیگری را که فکر می‌کنند مناسب است، محول کنند.

اگر به تنهایی از طریق این کدها کار می کنید، از این تکالیف برای آزمایش دانش خود استفاده کنید.

به این سوالات پاسخ دهید

سوال 1

کدام یک از اجزای زیر برای کار با Canvas مورد نیاز است؟ همه موارد کاربردی را انتخاب کنید.

Bitmap

Paint

Path

View

سوال 2

فراخوانی برای invalidate() چه کاری انجام می دهد (به طور کلی)؟

▢ برنامه شما را باطل می کند و دوباره راه اندازی می کند.

▢ نقشه را از بیت مپ پاک می کند.

▢ نشان می دهد که کد قبلی نباید اجرا شود.

▢ به سیستم می گوید که باید صفحه را دوباره ترسیم کند.

سوال 3

عملکرد اشیاء Canvas ، Bitmap و Paint چیست؟

▢ سطح طراحی 2 بعدی، نقشه بیت نمایش داده شده روی صفحه، اطلاعات یک ظاهر طراحی برای طراحی.

▢ سطح ترسیم سه بعدی، بیت مپ برای کش کردن مسیر، اطلاعات سبک برای طراحی.

▢ سطح طراحی 2 بعدی، نقشه بیت نمایش داده شده بر روی صفحه نمایش، یک ظاهر طراحی شده برای نمای.

▢ کش برای ترسیم اطلاعات، بیت مپ برای طراحی، اطلاعات یک ظاهر طراحی برای طراحی.

برای پیوند به دیگر کدلب ها در این دوره، صفحه فرود Advanced Android in Kotlin Codelabs را ببینید.