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

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

دوره بی ادبی:

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

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

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

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

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

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

سوال 1

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

Bitmap

Paint

Path

View

سوال 2

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

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

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

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

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

سوال 3

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

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

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

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

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

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